Following code was tested with ruby 1.9.3 .
All objects have to_s method
to_s method is define in
Object class and hence all ruby objects have method
Certain methods always call
to_s method. For example when we do string interpolation then
to_s method is called.
to_s is simply the string representation of the object.
Before we look at
to_str let’s see a case where ruby raises error.
Here is the result
In the first two cases the
to_s method of object
e was printed.
However in case ‘3’ ruby raised an error.
Let’s read the error message again.
In this case on the left hand side we have a string object.
To this string object we are trying to add object
Ruby could have called
to_s method on
e and could have produced the result.
But ruby refused to do so.
Ruby refused to do so because it found that the object we are trying to add to string is not of type String.
When we call
to_s we get the string representation of the string. But the object might or might not be behaving like a string.
Here we are not looking for the string representation of
What we want is for
e to behave a like string.
And that is where
to_str comes in picture. I have a few more examples to clear this thing so hang in there.
What is to_str
If an object implements
to_str method then it is telling the world that my class might not be
String but for all practical purposes treat me like a string.
So if we want to make exception object behave like a string then we can add
to_str method to it like this.
Now when we run the code we do not get any exception.
What would happen if Fixnum has to_str method
Here is an example where ruby raises exception.
Here Ruby is saying that Fixnum is not like a string and it should not be added to String.
We can make Fixnum to behave like a string by adding a
The practical usage of this example can be seen here.
In the above case ruby is refusing to invoke
to_s on “1” because it
knows that adding “1” to a string does not feel right.
However we can add method
to_str to Fixnum as shown in the last
section and then we will not get any error. In this case the result
will be as shown below.
A real practical example of defining to_str
Before the refactoring was done
Path is a subclass of
String. So it is String and it has all the methods of a string.
As part of refactoring
Path is no longer extending from
String. However for all practical purposes it acts like a string. This line is important and I am going to repeat it. For all practical purposes
Path here is like a
Here we are not talking about the string representation of
Path is so close to
String that practically it can be replaced for a string.
So in order to be like a
Path should have
to_str method and that’s exactly what was done as part of refactoring.
During discussion with my friends someone suggested instead of defining
to_str tenderlove could have just defined
to_s and the result would have been same.
Yes the result would be same whether you have defined
if you doing
However in the following case just defining
to_s will cause error.
Only by having
to_str following case will work.
So the difference between defining
to_str is not just what
you see in the output.
If a class defines
to_str then that class is telling the world that although my class is not
String you can treat me like a