2015-01-06 193 views
2

自的參考走過去此代碼上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 

的代碼傳遞而是使用了自變量是有點模​​糊的我。你可以很容易地用show方法替代to_s,並得到相同的結果。有人可以解釋兩種插值之間的區別,以及爲什麼/如何在這裏使用自我? 此外,如果沒有方法to_s,代碼將返回代理。在這裏定義to_s的意義是什麼?

+0

'to_s'是Ruby的標準轉換方法一個對象到一個字符串。通過在'class Item'中定義它,你可以在該類中使用它,所以當你用'#{self}'作爲一個字符串打印對象時,Ruby很聰明,可以用'to_s'方法。沒有'to_s'方法,你只需要檢查對象引用。 – lurker

回答

1

雖然這是真的,在你提供的例子,你可以只寫"The item name is: #{@item}",這並非總是如此。

由於CDub指出,字符串插值隱式地調用to_s。如果一個對象沒有定義一個方法,Ruby會在它的位置返回一個對象引用。在你給我們的例子中,寫作"The item name is: #{@item}"僅適用,因爲String實現了to_s。如果沒有,或者如果您使用Item來保存未實現to_s的對象,則最終會顯示對象的引用。

現在爲您的插值使用self@item之間的區別。 self指的是當前對象。當插入self時,您正在調用當前對象的方法to_s。當您插入@item時,您打電話給@itemto_s方法。在這種簡單的情況下,這不是一個問題,但讓我們看看更復雜一點。假設我們有兩個類,ItemOtherItem(我知道有創意的名字)。

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 

在這種情況下,Itemshow方法使用self,所以如果我們寫:

Item.new(OtherItem.new("potion")).show 

紅寶石稱之爲Item.show,這反過來,將調用self.to_s。由於self在這方面是一個Item,我們的產量將是:

"The item name is: I'm a chunky monkey!" 

但是,如果我們重新定義Item.show這樣的:

def show 
    puts "The item name is: #{@item}" 
end 

並試圖再次調用Item.new(OtherItem.new("potion")).showItem.show會叫@item.to_s,和相反,我們會得到:

"The item name is: potion" 
3

字符串插值隱式調用對象上的to_s方法。所以,當你在Item上定義to_s方法時,你是顯式地告訴那個對象如何在字符串中表示自己。在這種情況下使用self,因爲在Item對象的插值內存在對to_s的隱式調用。定義to_s顯式地告訴Item如何在字符串中呈現自己。

對於一些額外的細節,看看this excellent post on explicit vs. implicit conversion methods.