#to_s
is for representing an object as a String
. In your case, you need to convert the object to a String
, because String#+
only deals with String
s. In Ruby, type conversions are done with the three letter form of the to_X
methods, i.e. to_int
, to_ary
, to_hash
(someone can't count to three ...), to_str
and so on.
So, you need to implement to_str
, in order to make that work.
However, you should only implement to_str
, if your object actually is a string! If it's something else, you must not implement to_str
and rather have the clients explicitly represent it as a string using to_s
.
Basically, implementing to_str
in Ruby is like inheriting from String
in Java: it means that A
IS-A String
.
As an example, look at which classes in the Ruby core library actually implement the type conversion methods:
- the only class that implements
to_ary
, is Array
itself,
- the only class that implements
to_hash
, is Hash
itself and
- the only class that implements
to_str
, is String
itself.
This should show you that implementing to_str
is a very serious matter that should not be undertaken lightly.
The only conversion method that does not have only a trivial no-op implementation, is to_int
, which is also implemented by Float
and Numeric
. And actually, I think that is a mistake, since there is an infinite number of Float
s which aren't Integer
s. And Numeric
is a superclass of Integer
, so saying that every Numeric
IS-A Integer
is even more strange.