为什么你可以链接这个:
"Test".upcase.reverse.next.swapcase
但不是这样:
x = My_Class.new
x.a.b.c
其中
class My_Class
def a
@b = 1
end
def b
@b = @b + 2
end
def c
@b = @b -72
end
end
答案 0 :(得分:7)
upcase
,reverse
,next
和swapcase
方法都返回String
个对象,所有这些方法都是为了......你猜对了,{ {1}}对象!
当你调用一个方法时(通常比如99.9999%的时间),它会返回一个对象。该对象具有在其上定义的方法,然后可以调用它来解释为什么可以这样做:
String
您甚至可以根据需要多次拨打"Test".upcase.reverse.next.swapcase
:
reverse
所有因为它返回相同类型的对象,"Test".reverse.reverse.reverse.reverse.reverse.reverse.reverse.reverse
对象!
但是你不能用String
:
MyClass
要使其正常工作,x = My_Class.new
x.a.b.c
方法必须返回一个定义了a
方法的对象。现在,似乎只有b
的实例会有这种情况。要使其工作,您可以使对象本身的返回值为MyClass
,如下所示:
a
对此进行推断,def a
@b += 2
self
end
方法还需要返回b
,因为self
方法仅适用于c
类的实例。在此示例中MyClass
返回的内容并不重要,因为它是链的末尾。它可以返回c
,但它不能。薛定谔的 cat 方法。在我们打开盒子之前,没有人知道。
答案 1 :(得分:6)
作为对其他答案的支持,此代码:
"Test".upcase.reverse.next.swapcase
......与...几乎完全相同。
a = "Test"
b = a.upcase
c = b.reverse
d = c.next
e = d.swapcase
....除了我的代码上面有额外的变量留下指向中间结果,而原来没有留下额外的引用。如果我们使用您的代码执行此操作:
x = MyClass.new # x is an instance of MyClass
y = x.a # y is 1, the last expression in the a method
z = y.b # Error: Fixnums have no method named 'b'
使用Ruby 1.9的tap
方法,我们甚至可以更明确地说明这一点:
irb> "Test".upcase.tap{|o| p o}.reverse.tap{|o| p o}.next.tap{|o| p o}.swapcase
#=> "TEST"
#=> "TSET"
#=> "TSEU"
=> "tseu"
irb> class MyClass
irb> def a
irb> @b = 1
irb> end
irb> def b
irb> @b += 2
irb> end
irb> end
=> nil
irb(main):011:0> x = MyClass.new
=> #<MyClass:0x000001010202e0>
irb> x.a.tap{|o| p o}.b.tap{|o| p o}.c
#=> 1
NoMethodError: undefined method `b' for 1:Fixnum
from (irb):12
from /usr/local/bin/irb:12:in `<main>'
答案 2 :(得分:5)
函数中的最后一个表达式是其隐式返回值。如果你想链接这样的方法,你需要返回self
。
例如,您的a
方法当前正在返回1
。 b
不是数字的方法。你会想要修改它:
def a
@b = 1
self
end