#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 Strings. 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 Floats which aren't Integers. And Numeric is a superclass of Integer, so saying that every Numeric IS-A Integer is even more strange.