Ruby - reference to self in a class method
Passed this code on RubyMonk:
class Item
def initialize(item)
@item = item
end
def show
puts "The item name is: #{self}"
end
def to_s
"#{@item}"
end
end
Item.new("potion").show
The code goes through, but using the self variable is a little ambiguous for me. You could easily preempt to_s with yourself in the show method and get the same results. Can anyone explain the difference between interpolations and why / how themselves are used here? Also, without the to_s method, the code returns a proxy. What is the point of defining to_s here?
source to share
Although it is true that in the above example, you could have just written "The item name is: #{@item}"
, which is not always the case.
As CDub points out, string interpolation is implicitly called to_s
. If an object doesn't define a method to_s
, Ruby returns the object reference to its place. In the example you gave us, the record "The item name is: #{@item}"
only works because it String
implements to_s
. If it is not, or if you are using Item
to store an object that does not implement to_s
, you will get a reference to the object.
Now for the difference between using self
and @item
in your interpolation. self
refers to the current object. When you interpolate self
, you are calling the current object to_s
. When you interpolate @item
, you call the method @item
to_s
. This is not a problem in this simple case, but let's look at something a little more complicated. Let's say we have two classes: Item
and OtherItem
(declaration names, I know).
class Item
def initialize(item)
@item = item
end
def show
puts "The item name is: #{self}"
end
def to_s
"I'm a chunky monkey!"
end
end
class OtherItem
def initialize(item)
@otherItem = item
end
def to_s
"#{@otherItem}"
end
end
In this case, the method Item
show
uses self
, so if we were to write:
Item.new(OtherItem.new("potion")).show
Ruby will call Item.show
, which in turn will call self.to_s
. Since self
in this context is Item
, our output will be:
"The item name is: I'm a chunky monkey!"
If, however, we redefined Item.show
as follows:
def show
puts "The item name is: #{@item}"
end
And Item.new(OtherItem.new("potion")).show
after trying again , it Item.show
will call @item.to_s
and populate this instead so that we get:
"The item name is: potion"
source to share
String interpolation implicitly calls a method to_s
on an object. So, when you define a method to_s
on Item
, you are explicitly telling that object how to represent itself in relation to the string. self
is used in this case because Item
there is an implicit call in object interpolation to_s
. The definition to_s
explicitly tells Item
how to make yourself inside a string.
For more information, check out this excellent post on explicit or implicit conversion methods.
source to share