8

如下面的 ruby​​ 示例所示,我不能使用从 a 创建的lambda错误数量的参数调用 a,因为它对参数的数量非常严格:ProcMethod

# method with no args
def a; end

instance_eval(&method(:a))
# ArgumentError: wrong number of arguments (1 for 0)

method(:a).to_proc.call(1, 2, 3)
# ArgumentError: wrong number of arguments (3 for 0)

method(:a).to_proc.lambda?
# => true

如何从 a that is 或从 a获得Proc不是 lambda 的a ?ProcMethod

4

3 回答 3

2

没有办法做到这一点。

除了参数传递之外,我想知道您return对方法中的 a 有什么期望。它只能以lambda某种方式表现...

如果您真的必须这样做,您将需要构建自己的块,例如

Proc.new{ a }

对于更通用的方式,您必须检查arity该方法并仅传递所需的参数。

于 2013-04-25T13:31:58.633 回答
0

尝试将其包装在非 lambdaProc中,如下所示:

l = lambda {|a,b| puts "a: #{a}, b: #{b}" }
p = proc {|a,b| l.call(a,b) }

l.lambda?
#=> true
l.arity
#=> 2
l.call("hai")
#=> ArgumentError: wrong number of arguments (1 for 2)
l.call("hai", "bai", "weee", "womp", "woo")
#=> ArgumentError: wrong number of arguments (5 for 2)

p.lambda?
#=> false
p.arity
#=> 2
p.call("hai")
#=> a: hai, b: 
p.call("hai", "bai", "weee", "womp", "woo")
#=> a: hai, b: bai
于 2015-09-25T05:40:02.883 回答
0

转换LambdaProc

这是一种将 alambda或 amethod调用包装在 a 中Proc并使用 splat 处理任意数量的参数的解决方法:

def lambda_to_proc(lambda)
  Proc.new do |*args|
    diff = lambda.arity - args.size
    diff = 0 if diff.negative?
    args = args.concat(Array.new(diff, nil)).take(lambda.arity)

    lambda.call(*args)
  end
end

无论传递多少参数,这总是有效的;额外的参数将被删除并nil替换缺少的参数。


例子:

# lambda with two args
some_lambda = -> (a,b) { [a, b] }

# method with no args
def some_method; "hello!"; end

lambda_to_proc(some_lambda).call(5)
# => [5, nil]

lambda_to_proc(method(:some_method)).call(1,2,3)
# => "hello!"

注意:没有直接的方法可以将 lambda 或方法调用转换为 proc。这只是一种解决方法,显然比真正的交易慢(因为将一个电话包装在另一个电话中)。

于 2017-03-20T07:03:16.687 回答