4

我可以将参数传递给这样的函数:

func 1, 2, 3

或者我可以使用括号,如:

func(1, 2, 3)

后来我了解了list.each我传递的函数(不确定这是否真的发生了)一个块来对每个元素进行操作:

list.each {|x| puts x}

我假设这只是将块作为参数传递给each函数,但情况似乎并非如此,因为:

list.each( {|x| puts x} )

不起作用。

显示时我意识到了这一点:

5.upto(9) {|x| puts x}

如果块只是一个参数,这根本没有意义。

这里发生了什么?您可以向我指出任何资源来帮助解释这一点,也许还有其他不立即显而易见的结构事物?

4

2 回答 2

6

块确实有点特殊,但也可以用作参数。考虑这个函数:

def greet
  yield "Hello"
end

greet{ |greeting| puts "#{greeting} to you" }

你也可以像这样写完全相同的东西:

def greet(&block)
  block.call("Hello")
end

greet{ |greeting| puts "#{greeting} to you" }

# which is equivalent to:
my_proc = proc{ |greeting| puts "#{greeting}, nice to see you." }
greet(&my_proc)

最后,块是一种特殊形式的过程,具有特殊的语法,使它们更有用。但是您仍然可以访问 proc 并将它们传递出去。

于 2013-05-29T17:57:38.473 回答
4

方法可以只接受一个块,有点像一个特殊的参数。

def foo
  yield 123
end

foo { |x| puts x }
#=> 123

请注意该方法如何接受零参数,但仍接受块。这是因为这种将块挂在方法上的语法是一种特殊情况。传递给方法的任何块都可以使用yield关键字运行。您甚至可以询问是否使用block_given?关键字传入了一个块。

如果你想在局部变量中捕获它,你可以用一些特殊的语法来做到这一点。

def foo(a, &block)
  block.call a
end

foo(123) { |x| puts x }
#=> 123

在这种情况下,您将显式捕获块参数,并&在参数列表中使用该前缀。您现在拥有该块的变量,您可以发送call消息以执行该变量。只知道这必须出现在参数列表的末尾。

还要注意括号。foo(123) { |x| puts x }. 参数列表停止,括号关闭,附加块紧随其后。同样,因为这是语法中的一种特殊情况。

于 2013-05-29T18:00:29.047 回答