我可以将参数传递给这样的函数:
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}
如果块只是一个参数,那么根本没有意义。
这里发生了什么?您可以指点我帮助解释这个问题的任何资源,以及其他可能不是很明显的结构事物吗?
答案 0 :(得分: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,它具有特殊的语法,使它们更有用。但你仍然可以访问过程并传递它们。
答案 1 :(得分: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
消息以便执行。只要知道这必须出现在参数列表的末尾。
还要注意那些parens。 foo(123) { |x| puts x }
。参数列表停止,parens关闭,附加的块后来。同样,因为这是语法中的特殊情况。