2013-05-29 80 views
4

我可以通过函数的参数是这样的:块是否作为参数传递?

func 1, 2, 3 

或者我可以用这样的括号:在我了解到像list.each功能,我通过(不知道

func(1, 2, 3) 

以后如果这是什么真的发生)一个块操作每个元素:

list.each {|x| puts x} 

我假设这只是通过块作为参数的each功能,但是这似乎并没有因为情况:

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

不起作用。

我意识到这一点时表示:

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

这没有任何意义可言,如果该块是一个简单的说法。

这是怎么回事吗?你可以指出我的任何资源来帮助解释这一点,也许还有其他一些并不明显的结构性事物?

+0

您可能会发现这是一个有益的出发点:[http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/](http://www.robertsosinski 。com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas /) – Chris

+0

这是一个专门为将块传递给函数而创建的特殊语法。对于每个函数调用,您可以在常规参数列表之外传递一个块。该块仍被追加到被调用函数的上下文中的参数列表中。 – meagar

+0

@Matt - 由于您正在学习Ruby,请浏览:http://www.codecademy.com/tracks/ruby - 对于想学习Ruby语言的核心基础知识的人来说真的是非常好的资源 – David

回答

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) 

最后,块是用一种特殊的语法,这使得它们更便于使用特效的一种特殊形式。但是你仍然可以访问procs并传递它们。

+0

这样做很有意义,谢谢! –

+4

+1。我会补充说,有几个陷阱。块在技术上是Proc对象,与lambda对象类似但不完全相同。他们各自的行为与例如例如,图示参数不完全相同。 (当然,这些错误与Ruby bug有关,自从我上次使用Ruby以来,这些错误可能已经得到修复,所以使用Ruby做了大量的工作,但当时存在诸如此类的生动细节。)另外,请注意,通过使用'&block'语法,明确地*在每次调用时创建一个Proc对象 - 即使没有传递任何代码块,由于创建了过多的对象,导致代码变慢。 –

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关闭,并附加块之后。同样,因为这是语法中的特例。

+0

谢谢。 你可以调用类似于:'def two_func_in(&func1,&func2)'?那个电话会是什么样子?编辑:你说“方法可以接受一个块”。这是这个问题的答案吗? –

+0

'def two_func_in(&func1,&func2)'不是有效的红宝石。你只能对方法附加一个块。但还有其他一些方法可以将一些代码作为基本的简单参数传入。就像[Proc](http://ruby-doc.org/core-1.9.3/Proc.html)对象一样,尽管处理这个对象的语法是不同的。 –