Ruby - 类方法中self的引用

时间:2015-01-06 02:29:01

标签: ruby class methods

在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方法中使用self轻松取代to_s并获得相同的结果。有人可以解释两种插值之间的区别以及为什么/如何使用自我? 此外,如果没有方法to_s,代码将返回代理。在这里定义to_s有什么意义?

2 个答案:

答案 0 :(得分:3)

字符串插值隐式调用对象上的to_s方法。因此,当您在to_s上定义Item方法时,您显式地告诉该对象如何根据字符串表示自己。在这种情况下使用self,因为在to_s对象的插值中隐式调用Item。明确定义to_s 告诉Item如何在字符串中呈现自己。

有关其他详细信息,请查看this excellent post on explicit vs. implicit conversion methods.

答案 1 :(得分:1)

虽然在你提供的例子中,你可以写"The item name is: #{@item}",但情况并非总是如此。

正如CDub指出的那样,字符串插值隐式调用to_s。如果对象没有定义to_s方法,Ruby会在其位置返回一个对象引用。在您给我们的示例中,编写"The item name is: #{@item}"仅适用,因为String实现了to_s。如果没有,或者您使用Item来保存未实现to_s的对象,则最终会得到对象的引用。

现在,在插值中使用self@item之间存在差异。 self指的是当前对象。插入self时,您将调用当前对象的to_s方法。当您插入@item时,您正在调用@item的{​​{1}}方法。在这个简单的例子中,这不是问题,但让我们看一些更复杂的东西。假设我们有两个类,to_sItem(创意名称,我知道)。

OtherItem

在这种情况下, 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 的{​​{1}}方法使用Item,所以如果我们要写:

show

Ruby会调用self,而Item.new(OtherItem.new("potion")).show 会调用Item.show。由于该上下文中的self.to_sself,因此我们的输出将为:

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")).show会致电Item.show,然后填写相应内容,以便我们得到:

@item.to_s
相关问题