簡體   English   中英

如何將方法或lambda轉換為非lambda proc

[英]How to convert method or lambda to non-lambda proc

如下面的ruby示例所示,我不能將具有錯誤數量的參數的lambda稱為從Method創建的Proc ,因為它對參數的數量是嚴格的:

# 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不是,無論是從一個lambda Proc即或者從一個Method

沒有辦法做到這一點。

除了參數傳遞,我想知道你對方法中的return會有什么期望。 它只能以lambda方式行事......

如果你真的必須這樣做,你需要建立自己的塊,例如

Proc.new{ a }

對於更通用的方法,您必須檢查方法的arity並僅傳遞所需的參數。

嘗試將其包裝在非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

Lambda轉換為Proc

這是一個在Proc中包裝lambdamethod調用的解決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。 這只是一種解決方法,顯然比真實交易慢(因為在另一個調用中包含一個調用)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM