Ruby中块和块之间的区别

col*_*rco 57 ruby

为什么有时我应该使用块和其他时间并阻止接受块的函数内部?

Aug*_*aas 99

block只是一个局部变量,&block是对传递给该方法的块的引用.

def foo(block = nil)
  p block
end

foo # => nil
foo("test") # => test
foo { puts "this block will not be called" } # => nil

def foo(&block)
  p block
end

foo # => nil
foo("test") # => ArgumentError: wrong number of arguments (1 for 0)
foo { puts "This block won't get called, but you'll se it referenced as a proc." }
# => #<Proc:0x0000000100124ea8@untitled:20>
Run Code Online (Sandbox Code Playgroud)

您还可以&block在调用方法时将proc作为块传递给方法,这样您就可以像使用块一样使用proc.

my_proc = proc {|i| i.upcase }

p ["foo", "bar", "baz"].map(&my_proc)
# => ["FOO", "BAR", "BAZ"]

p ["foo", "bar", "baz"].map(my_proc)
# => ArgumentError: wrong number of arguments (1 for 0)
Run Code Online (Sandbox Code Playgroud)

变量名称block并不意味着什么特别的.&strawberries如果你愿意,你可以使用&符号是关键.

您可能会发现本文很有帮助.


Chu*_*uck 27

在参数列表中,&whatever获取传递给方法的块并将其包装在Proc对象中.Proc存储在一个名为的变量中whatever(其中可以是你在&符号后键入的任何名称,当然 - 通常是"块").在方法调用之后,&whatever语法将Proc转换为块.所以如果你定义一个这样的方法:

def thing(&block)
  thing2 &block
end
Run Code Online (Sandbox Code Playgroud)

您正在定义一个方法,该方法接受一个块,然后使用该块调用另一个方法.


Mar*_*rth 16

如果你没有设置&before块,Ruby将无法识别它与你传递给函数的"块"的关系.这里有一些例子.

def f(x, block); end
f(3) { 2+2 }    # gives an error, because "block" is a
                # regular second argument (which is missing)

def g(x, &block); end
g(3) { 2+2 }    # legal

def h(x); end
h(3) { 2+2 }    # legal
Run Code Online (Sandbox Code Playgroud)

以后用于函数:

def x(&block)   # x is a 0 param function
  y(block)      # y is a 1 param function (taking one "Proc")
  z(&block)     # z is a 0 param function (like x) with the block x received
end
Run Code Online (Sandbox Code Playgroud)

所以,如果你调用z(&block)它(差不多!!)就像调用一样z { yield }:你只需将块传递给下一个函数.