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 <daniel@brockman.se>
So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.