【问题标题】:Ruby - reference of self in the class methodRuby - 在类方法中引用 self
【发布时间】:2015-03-03 16:19:29
【问题描述】:

在 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

代码通过了,但 self 变量的使用对我来说有点模棱两可。您可以在 show 方法中轻松地将 to_s 替换为 self 并获得相同的结果。有人可以解释这两种插值之间的区别以及为什么/如何在这里使用 self 吗? 此外,如果没有 to_s 方法,代码将返回一个代理。这里定义to_s有什么意义?

【问题讨论】:

  • to_s 是将对象转换为字符串的标准 Ruby 方法。通过在class Item 中定义它,您已经使其在该类中可用,因此当您使用#{self} 作为字符串打印对象时,Ruby 足够聪明,可以使用to_s 方法。如果没有 to_s 方法,您只需检查对象引用。

标签: ruby class methods


【解决方案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 时,您正在调用 @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

Ruby 会调用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"

【讨论】:

    【解决方案2】:

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

    更多详情,请查看this excellent post on explicit vs. implicit conversion methods.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-28
      • 2011-05-19
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多