From: Daniel Schierbeck Date: 2006-05-13T04:48:30+09:00 Subject: Re: Newb question - object type tests? 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. >> 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. 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. >> 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). >> 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. Cheers Daniel