我会一次拿这一个。完全脱离method_missing
,因为这只会让人感到困惑。这实际上完全没有关系。
splat *
有2件事。在方法定义的参数中,它将多个参数吸收到一个数组中。当在方法调用中使用时,它将数组划分为单独的参数。使用这两种方法可以将任意数量的参数转发给其他方法。
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
由于您基本上是转发所有参数,这是相同的模式。
&
用于块参数。每个方法调用都可以有其中的一个,它是挂起的块。这是一个特殊的论点,因为它不直接引入论证。通过捕获添加&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
注意,图示并不仅仅适用于方法的参数定义/参数列表。它也适用于块参数定义/参数列表,*和*赋值。 –