Eric Hodel wrote:
> On Aug 8, 2006, at 10:35 AM, Daniel Schierbeck wrote:
>> Eric Hodel wrote:
>>> On Aug 8, 2006, at 2:45 AM, Daniel Schierbeck wrote:
>>>> Eric Hodel wrote:
>>>>> On Aug 7, 2006, at 3:30 PM, Daniel Schierbeck wrote:
>>>>>> Eric Hodel wrote:
>>>>>>> On Aug 6, 2006, at 7:55 AM, Daniel Schierbeck wrote:
>>>>>>>> I'd do it like this:
>>>>>>>>
>>>>>>>>   class SomeClass
>>>>>>>>     def foo(obj)
>>>>>>>>       str = obj.to_str
>>>>>>> Don't call to_str, call to_s.
>>>>>>>>       puts str + str # or `str * 2'
>>>>>>>>       puts str.reverse
>>>>>>>>     end
>>>>>>>>   end
>>>>>>>>
>>>>>>>> Though I know some very smart people on this list disagree with me.
>>>>>>> Only because you call to_str.  This is not the reason it exists.
>>>>>>
>>>>>> I favor using #to_str when I want to treat an object like a 
>>>>>> string. Practically all classes implement #to_s, so it's not 
>>>>>> really a type restriction. We're trying to solve two different 
>>>>>> problems -- I want to let the caller know if he sent the wrong 
>>>>>> kind of object as an argument. That's type checking. If you want 
>>>>>> to convert any object received to a string, then we're talking 
>>>>>> type conversion, which I think should be left to the caller in 
>>>>>> many cases. But that's just my humble opinion, of course.
>>>>> #to_str is not for type conversion.  It exists for classes that 
>>>>> duck type completely to String and is called when a C string is 
>>>>> needed by a method in String to improve performance.  In other 
>>>>> words, #to_str should only be implemented on objects that are 
>>>>> already "Strings".
>>>>
>>>> Exactly my point. I think we're misunderstanding each other here; if 
>>>> you have an object that is a representation of a string, say
>>>>
>>>>   # Bad example, but hey...
>>>>   class Name
>>>>     attr_accessor :first, :last
>>>>
>>>>     def initialize(first, last)
>>>>       @first, @last = first, last
>>>>     end
>>>>   end
>>>>
>>>> Then it's okay for it to have #to_str, e.g.
>>>>
>>>>     def to_str
>>>>       "#{first} #{second}"
>>>>     end
>>>>
>>>> My own logic is this: if an object is a natural string, but with 
>>>> *more* information, then it can have #to_str. Otherwise, stick to 
>>>> #to_s.
>>> A Name is not a String.  You don't #each it, you don't #chop it, its 
>>> never #empty?, ...
>>
>> That's why you use the return value of #to_str.
> 
> You don't call #to_str, String calls #to_str when it needs to.

So the implementation of e.g. String#+ is wrong? Or is it okay for a 
method on String to call #to_str on its arguments?

>> I'm not saying this is how everybody should do it, I'm just saying 
>> that it's a very smart way to handle types -- duck typing being a very 
>> similar way.
> 
> It isn't a smart way to handle types, it is a broken and wrong way to 
> handle types.

I'm sorry, but I have to disagree. Read the RomanNumeral example again 
-- it's an integer, but it doesn't inherit from Integer.


Daniel