3

可能重复:
Ruby 中的 &block 是什么?它是如何在这里通过一个方法的?

我不明白这&block部分,它有什么作用?

这是一个例子:

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

4 回答 4

6

Blocks让您有机会声明回调以传递给方法。

这里&的关键 - 就像提到的@pst 一样,它将块“提升”到 Proc 并将 Proc 绑定到具有给定名称的变量。

&

def time(&block)
  puts block
end

time
# => nil
time { foo }
# => #<Proc:0x00029bbc>

没有 &

def time(block)
  puts block
end

time { foo }
# => ArgumentError: wrong number of arguments (0 for 1)
# Because & isn't included, the method instead expected an arguement,
# but as a block isn't a arguement an error is returned.
于 2012-12-01T00:14:02.690 回答
4

回答“我如何将它传递给另一种方法?” 布赖恩评论:

像这样:

def compose init_value, n=2, &b
  if n==0 then init_value else
    b.call( compose init_value, n - 1, &b )
  end
end

compose 2 do |n| n * n end
#=> 16
compose 2, 4 do |n| n * n end
#=> 65536
compose 2, 4 do |n| n * 0.5 end
#=> 0.125

这是一种递归方法,可以多次递归地将同一块应用于一个数字。在这里,打包到b参数中的块被调用,但同时它被递归地传递给compose方法,而n参数减 1。同样,b可以传递给任何方法,如map, reduce, 任何东西。

然而,如果您不需要将块传递给另一个方法,您可以简单地使用yield

def apply_block_to_1_2_3
  return yield( 1 ), yield( 2 ), yield( 3 )
end

apply_block_to_1_2_3 { |n| n * n }
#=> [1, 4, 9]

愿原力与你同在。

于 2012-12-01T01:10:28.070 回答
3

它将块转换为可以传递给另一个方法的 proc 对象。

于 2012-12-01T00:14:19.247 回答
1

当您使用块调用方法时,有两种使用该块的方法:

  • 调用yield内部方法
  • 通过添加到它来将其转换为Proc对象&

使用第二种方法,您可以将其传递给另一种方法。

所以在你的情况下,它将给定的块转换为 aProc并用它调用method_name

把它想象成你可以像任何参数一样传递一个块。

于 2012-12-01T00:21:36.250 回答