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