Hi --

On Mon, 13 Aug 2007, Nasir Khan wrote:

> Hi,
> I have two related questions on to_str behavior. AFAIK to_str does automatic
> coercion to string wherever one is required, it is to be provided for
> objects that exhibit string like behavior. But this mental model did not
> match up with my test -
>
> Consider a simple class
>
> class B
>    def initialize(str)
>      @value = str
>    end
>    def to_s
>      @value
>    end
>    def to_str
>      to_s
>    end
>  end
>
> irb(main):038:0> x = B.new("hello")
> => #<B:0x27f1550 @value="hello">
>
> irb(main):042:0> a = "hello"+x
> => "hellohello"
>
> So far so good. Concatenation automatically happend. Then I went on to write
> a test -
>
> class MyTest < Test::Unit::TestCase
>   def test_equality
>     x = B.new("hello")
>     assert_equal("hello", x)
>   end
> end
>
> Which failed to my surprise.
>
>  1) Failure:
> test_equality(MyTest) [(irb):49]:
> <"hello"> expected but was
> <#<B:0x27549bc @value="hello">>.
>
> 1 tests, 1 assertions, 1 failures, 0 errors

You're making a strange assumption, namely that Ruby cares whether or
not your assertion succeeds :-)  All that's happening is:

   "hello" == x

and String#== does not do any kind of string conversion on its
operand.  It wouldn't be appropriate, because there's no reason to
think you want every == test to pass.  That's different from string
concatenation, where you would never have any reason to do:

   "str" + x

unless the operation was expected to work.

#to_str is a very "niche" method.  It doesn't morph objects into
strings; rather, it provides an automatic string representation for
cases where it makes no sense for anything but a string to be
involved.


David

-- 
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
   RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
     & consulting:  Ruby Power and Light, LLC (http://www.rubypal.com)