在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有什么意义?
答案 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_s
和Item
(创意名称,我知道)。
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_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")).show
会致电Item.show
,然后填写相应内容,以便我们得到:
@item.to_s