From: Daniel Brockman Date: 2005-07-27T10:31:40+09:00 Subject: Re: defining to_s works oddly? Hi Martin, > Am I the only one that finds it odd that if I define a > to_s function for a class, that if I do > > puts obj > > I won't get errors, but if I try something like > > s = String.new > s += obj > > I get a [TypeError] You're probably not the only one. The reason why ‘puts’ converts its argument using ‘to_s’ but String#+ doesn't is far from obvious. > It's no prob to write obj.to_s, it's just I expected the > first version to call to_s automatically... As James Edward Gray II quoted Why saying, “to_str is an implicit cast, whereas to_s is an explicit cast,” and you could probably redefine String#+ to perform the explicit cast instead of the implicit with no problems resulting. But I wouldn't do that. There is a significant difference between ‘"#{foo}"’ (or ‘puts foo’) and ‘"bar" + foo’: The former *must* result in a string, whereas the latter could reasonably result in something other than a string. Consider these two expressions: "1" + 2 and 1 + "2" Current Ruby behavior is to reject both with type errors. See, Fixnum#+ implicitly casts its argument into a number, and String#+ implicitly casts its argument into a string, but neither argument can be implicitly casted that way. [Again, the term “implicit cast” is not an exact description of what happens, but rather a shorter way of saying “convert if possible and fail otherwise.”] You could make either method use an explicit cast instead of an implicit, but if you make both explicit you would be in the following weird situation: "1" + 2 #=> "12" 1 + "2" #=> 3 Assuming you agree that this asymmetry is unacceptable, the question is, which cast should take precedence? Perl avoids this ambiguity by letting "1" == 1, so that "1" + 2 == 1 + "2" == "3" == 3. Ruby avoids it by requiring an explicit cast: "1" + 2.to_s #=> "12" 1.to_s + "2" #=> "12" 1 + "2".to_i #=> 3 "1".to_i + 2 #=> 3 I know this message doesn't provide any solutions, but I hope it can help you accept Ruby's behavior as reasonable (something I consider very important for trust reasons). -- Daniel Brockman So really, we all have to ask ourselves: Am I waiting for RMS to do this? --TTN.