On May 12, 2006, at 12:48 PM, Daniel Schierbeck wrote:
> Eric Hodel wrote:
>> On May 12, 2006, at 3:14 AM, Daniel Schierbeck wrote:
>>> If you want to be more Rubyish, try this:
>>>
>>>   item = ["hello"]
>>>   item.respond_to? :to_ary  => true
>>>   item = "hello"
>>>   item.respond_to? :to_str  => true
>> What you really want is to_a and to_s, not to_ary and to_str.
>> The to_xxx methods are used to convert an object that is an XXX  
>> representation into an XXX object when there is no inheritance  
>> relationship.
>
> No, the #to_x methods do that. Only objects that are "strings", but  
> not necessarily instances of String, should define #to_str.

You are confusing is-a with has-a and I used bad terminology.

Objects that define #to_xxx are XXX versions (duck type to XXX) while  
objects that define #to_x have X representations.

>>> So if you're writing a method that requires a string, just do this:
>>>
>>>   def foo(bar)
>>>     str = bar.to_str
>>>     str.split(...
>>>   end
>> The Ruby way to write that is:
>> def foo(bar)
>>   bar.split(...)
>> end
>
> Funny, that isn't the behavior of, say, this
>
>   [].each(&obj)
>
> Here, `obj' is converted to a Proc behind the scenes, by calling  
> #to_proc on `obj'. Alternatively, #each could just call #call on  
> the object for each object in the array, but it doesn't; it first  
> calls #to_proc.

The & operator performs proc conversion.  This cannot be done inside  
#each because the method signature is wrong.

def each(&block); end # implicit block
def each(block); end # no implicit block

> Almost every single (all?) class in Ruby defines a #to_s method, so  
> the return value of it does not necessarily match the object  
> itself. Take Proc#to_s for example.

has-a vs is-a.

See [ruby-talk:96552], the thread starting at [ruby-talk:96554] and  
[ruby-talk:96567].

>>> That way, all classes that consider themselves strings need only  
>>> define a #to_str method.
>> I've never written a class that considered itself a string.  Had a  
>> string representation, yes, but not one that was a String.
>
>   class Name
>     attr_accessor :first, :last
>
>     def initialize(first, last)
>       @first, @last = first, last
>     end
>
>     def to_str
>       to_s
>     end
>
>     def to_s
>       "#{first} #{last}"
>     end
>   end
>
> This may not be the best example, but you get the idea. An Email  
> class may be better, but that'd be more complex (regexes and such).

Names don't duck-type to Strings.  You don't sub! them, you don't  
iterate over them, you  don't do anything else you do with a String.   
If your object doesn't duck-quack like an XXX you shouldn't be  
defining #to_xxx.

#to_ary has utility with various data structures including linked-lists.

>>> If they actually do define the same methods as String, #to_str  
>>> can just return `self'; otherwise it can return a string  
>>> representation.
>> No. to_xxx needs to return as XXX object, not self, unless it is  
>> defined on the XXX class.  For example String#to_str would return  
>> self.
>
> For it to work with native Ruby methods, yes. But no purist is  
> going to check the class of the object returned anyway. If the  
> object doesn't respond to a method defined by the class it way  
> "converted" to, that's the fault of the maker of the object, not  
> the receiver.

No.  That isn't what #to_xxx is for.  Read [ruby-talk:96567].

-- 
Eric Hodel - drbrain / segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com