Ruby Koans 关于消息传递 "send" block 和参数

标签 ruby methods block send splat

我正在研究 Ruby Koans about_message_passing.rb 并获得了用于 method_missing 的代码,如下所示:

def method_missing(method_name, *args, &block)
  @messages << method_name
  @object.__send__(method_name, *args, &block)
end

这段代码似乎可以工作,但我不太明白为什么 *args 中需要 splat, block 中需要 &。

如果我正在定义一个方法,我知道 * 和 & 分别用于表示数组参数和 block 参数,但是当它们与 send 方法一起使用以调用对象上的方法时,这意味着什么?

最佳答案

我一次拿这些。将 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

因为您基本上是在转发所有参数,所以这是相同的模式。


& 用于 block 参数。每个方法调用可能只有其中一个,它是卡在末尾的 block 。这是一个特殊的参数,因为它不直接进入参数。您可以通过捕获 add &someblock 作为方法 定义 中的最后一个参数来将 block 捕获到变量。

然后您可以使用相同的语法在方法调用中传递一个 block 。

def foo(&block)
  bar(&block)
end

def bar
  yield
end

foo { puts 'hello' } # prints hello

这允许您将挂起的 block 传递给另一个方法,而无需调用它。它并不总是必需的,因为您通常只使用 yield 来执行传递的任何 block 。但是如果你想做一些除了执行之外的事情,你需要捕获对 block 本身的引用。


因此,如果将这两个东西结合起来,就会得到最终的方法转发器。您捕获所有任意数量的参数,以及悬在末尾的任何 block ,并将它们发送到另一个方法。

# forwards everything to the method `bar`
def foo(*args, &block)
  bar(*args, &block)
end

最后,send 只是一个方法。它需要一个方法名称,后跟任意数量的参数(不是数组),并且可以选择处理一个挂起的 block 。

换句话说:

foo.send methodName, *args, &block

关于Ruby Koans 关于消息传递 "send" block 和参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14047942/

相关文章:

ruby-on-rails - RSpec、Capybara、JavaScript 测试未正确回滚数据库

ruby - 了解 ruby​​-prof 输出

ruby-on-rails - accepts_nested_attributes_for rails 4 没有删除

java - 如何使用线程运行类的方法

javascript - 如何将数字插入数组?

ios - 从 Objective-c 快速进行 block 转换

ruby-on-rails - rails 查询超时::错误:执行已过期

java - 如果发现重复项,则替换数组中的数字

ios - 如何在 AdMob 中找到广告商网址以便我可以屏蔽它

perl - 将 perl 的排序函数包装在一个对象中