----- Original Message -----
From: "Shashank Date" <sdate / everestkc.net>
Newsgroups: comp.lang.ruby
To: "ruby-talk ML" <ruby-talk / ruby-lang.org>
Sent: Thursday, June 12, 2003 10:48 PM
Subject: Re: Confused about to_s in Ruby / irb


>
> "Hal E. Fulton" <hal9000 / hypermetrics.com> wrote in message
> > The to_str method is used when an objects wants to "masquerade"
> > as a string.
>
> Meaning ?
>
> > One common difference is that the latter will
> > typically preserve all information, whereas the
> > former may only present enough to render the object
> > in a printable form. (At least I think I've seen
> > that distinction somewhere.)
>
> Forgive me for being dense. Can you please explain this more ?
> Maybe with an example ? All I have is a reference from PickAxe:

You're not dense. I still find it highly non-obvious.

All I know about this I learned from Dave Thomas.

I think I can get away with quoting this much of _The
Ruby Way_, chapter 5. See below. Just don't tell the
l-a-w-y-e-r-s.

Cheers,
Hal

========================================================

Sometimes an object comes in exactly the right form at the right time, but
sometimes we need to convert it to something else or pretend it's something
it isn't. A good example is the well-known to_s method.

Every object can be converted in some fashion to a string representation.
But not every object can successfully masquerade as a string. That in
essence is the difference between the to_s and to_str methods. Let's
elaborate on that.

Methods such as puts and contexts such as #{...} interpolation in strings
expect to receive a String as a parameter. If they do not, they ask the
object they did receive to convert itself to a String by sending it a to_s
message. This is where you get to specify how your object will appear when
displayed; simply implement a to_s method in your class that returns an
appropriate String.

    class Pet

      def initialize(name)
        @name = name
      end

      # ...

      def to_s
        "Pet: #@name"
      end

    end

Other methods (such as the String concatenation operator +) are more picky;
they expect you to pass in something that is really pretty close to a
String. In this case, Matz decided not to have the interpreter call to_s to
convert non-string arguments, as he felt this would lead to too many errors.
Instead, the interpreter invokes a stricter method, to_str. Of the built-in
classes, only String and Exception implement to_str, and only String,
Regexp, and Marshal call it. Typically when you see the runtime error
TypeError: Failed to convert xyz into String, you know that the interpreter
tried to invoke to_str and failed.

You can implement to_str yourself. For example, you might want to allow
numbers to be concatenated to strings:

  class Numeric

    def to_str
      to_s
    end

  end

  label = "Number " + 9      # "Number 9"