如何将方法或 lambda 转换为非 lambda proc
Posted
技术标签:
【中文标题】如何将方法或 lambda 转换为非 lambda proc【英文标题】:How to convert method or lambda to non-lambda proc 【发布时间】:2013-04-18 07:18:46 【问题描述】:如下面的 ruby 示例所示,我不能调用带有错误数量的参数的 lambda
,因为它对参数数量非常严格:
# 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
如何从Proc
或Method
获得不是lambda 的Proc
?
【问题讨论】:
据我所知,您不能将方法或 lambda 转换为非 lambda proc。你想完成什么? @WallyAltman 块的调用语义,首先是关于参数的数量,但还有其他一些区别。 【参考方案1】:没有办法做到这一点。
除了参数传递之外,我想知道您对方法中的return
有什么期望。它只能以lambda
方式运行...
如果你真的必须这样做,你将需要构建自己的块,例如
Proc.new a
对于更通用的方法,您必须检查方法的arity
并仅传递所需的参数。
【讨论】:
我想这不太可能因为return
、next
和break
,作为临时措施,我要么用 splat 编写方法,要么让它们返回 Proc
。有没有办法证明做不到?
@michelpm:没有证据,抱歉。【参考方案2】:
尝试将其包装在非 lambda Proc
中,如下所示:
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
【讨论】:
【参考方案3】:将Lambda
转换为Proc
这是一种解决方法,它在 Proc
中包装了 lambda
或 method
调用,并使用 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。这只是一种解决方法,显然比真正的交易慢(因为将一个调用包装在另一个调用中)。
【讨论】:
请记住,如果您的lambda
可以采用默认参数,这将不起作用。例如。 some_lambda = -> (a, b = 0) [a, b]
在使用 lambda_to_proc
调用时会引发 ArgumentError
。一种解决方法是使用lambda.parameters.length
而不是lambda.arity
。以上是关于如何将方法或 lambda 转换为非 lambda proc的主要内容,如果未能解决你的问题,请参考以下文章
将多级 for 循环转换为 linq 或 lambda 表达式
如何从 PostgreSQL 查询转换为 LINQ 或 lambda 表达式
如何使用Lambda从Amazon AWS中提取和转换单个dynamodb元素