From: Daniel Schierbeck Date: 2006-08-09T02:35:12+09:00 Subject: Re: How to react on nil or wrong object-type as parameter 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. If only String had #to_str, then why have it in the first place? Why not just check the class? 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. Cheers, Daniel