2013-03-25 18 views
1

例如,当我使用yield(param)但通过块{| p1,p2 | ...}它有两个参数。如果我不知道什么参数需要花费时间,我应该如何防止这种情况发生?如何防止参数在收益中不匹配时的情况?

+1

它是如何产生的问题?我测试了这个,它在Ruby 1.9.3中工作正常。你可以编辑和添加一个不适合你的简单测试用例 – 2013-03-25 05:02:32

+0

从逻辑上说,你希望yield只能处理一个参数,但实际上你只能传递两个参数。所以这在逻辑上不正确,是吗? – OneZero 2013-03-25 05:05:08

+1

目前尚不清楚“防”的含义。你想静静地取消参数应用到'yield',还是你想提出一个错误? – sawa 2013-03-25 05:08:45

回答

1

使用块中的图示,或简单地传递变量,可以在那里,测试它们的定义:

def foo 
    yield 1, 2, 3 
end 

foo do |*args| 
    if 3 == args.length 
    # ... then I know I'm dealing with 3 args 
    end 
end 

foo do |a, b, c, d| 
    if !d.nil? 
    # ... then I know i was passed `d` 
    end 
end 
+1

但是这要求调用者(定义块的那个)负责检查块给出的参数,而这听起来像问题是询问如果被调用的方法在接受块错误的论点数量......除非我误解? – 2013-03-25 05:32:15

+1

我把它理解为相反,但也许我是一个误解。这对我来说很有意义,因为在编写方法时,你知道你正在产生什么,但是在使用yield时,没有明确的方法来告诉将有多少参数传递给块。 – numbers1311407 2013-03-25 05:39:19

+0

对,同意。在我的回答中,我试图向@ user1229490说明,使用方法块,实际上没有办法指出这一点,这意味着您需要使用其他类型的闭包之一,例如lambda(尽管您失去了语法糖) 。 – 2013-03-25 05:41:57

0

参见关于Ruby块,特效和Lambda表达式这个优秀的博客文章:

Understanding Ruby Blocks, Procs and Lambdas

它解释说,块(如foo() {|p1,p2| ...}传递的一个)像Proc S,它不检查传递的参数的数量。然而,兰巴达斯呢。因此,如果您需要严格检查参数的数量,则可能会从接受方法中的Block切换到接受Lambda作为方法参数。

0

您应该使用块参数而不是yield,它提供比yield更多的信息,例如arity。

def foo *params, &block 
    ... 
    block.call(*params) if params.length == block.arity 
    ... 
end 

foo(3){|x| puts x*3} # => 9 
foo(3, 4){|x| puts x*3} # => Does not do anything 
相关问题