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?

+3


source to share


2 answers


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"

      

+1


source


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.

+3


source







All Articles