我会一次拿这些。完全摆脱method_missing
这一点,因为它只会让正在发生的事情变得混乱。它实际上与此完全无关。
splat*
做了两件事。在方法定义的参数中,它将多个参数吸收到一个数组中。在方法调用中使用时,它将一个数组分解为单个参数。使用两者允许您将任意数量的参数转发给另一个方法。
def foo(*args)
bar(*args)
end
def bar(a, b, c)
puts a
puts b
puts c
end
foo(1,2,3) # prints 1, 2 and then 3
由于您基本上是在转发所有参数,因此这是相同的模式。
&
用于块参数。每个方法调用都可以有其中一个,它是挂在最后的块。这是一个特殊的论点,因为它不直接进入论点。您可以通过捕获 add&someblock
作为方法定义中的最后一个参数来将块捕获到变量中。
然后,您可以使用相同的语法在方法调用中传递一个块。
def foo(&block)
bar(&block)
end
def bar
yield
end
foo { puts 'hello' } # prints hello
这允许您将挂起的块传递给另一个方法,而无需调用它。它并不总是必需的,因为您通常只是yield
用来执行传递的任何块。但是如果你想做一些除了执行它之外的事情,你需要捕获对块本身的引用。
所以如果你把这两件事结合起来,你就得到了终极的方法转发器。您捕获所有任意数量的参数,以及挂在末尾的任何块,并将它们发送到另一个方法。
# forwards everything to the method `bar`
def foo(*args, &block)
bar(*args, &block)
end
最后,send
只是一种方法。它需要一个方法的名称,后跟任意数量的参数(不是数组),并且可以选择处理挂起的块。
换句话说:
foo.send methodName, *args, &block