假設我有一個函式 foo:
def foo(A, B, C)
A B C
end
我這樣稱呼它,只有最后一個引數發生變化:
foo("foo", "bar", "123")
foo("foo", "bar", "456")
foo("foo", "bar", "789")
如何“烘焙”或“預填充”不變的論點?所以也許我會得到一個新的可呼叫物件foo_baked,foo_baked("123")與foo("foo", "bar", "123")?
并像這樣使用它:
foo_baked = ...?
foo_baked("123")
foo_baked("456")
foo_baked("789")
uj5u.com熱心網友回復:
一些答案/評論提到了 currying,但沒有一個使用Ruby 中存在的curry方法:
def foo(a, b, c)
a b c
end
foo_baked = method(:foo).curry.call('foo', 'bar')
# this returns "foobar123"
foo_baked.call('123')
# ArgumentError (wrong number of arguments (given 4, expected 3))
foo_baked.call('123', '234')
基本上,Method#curry回傳一個 curried proc:一個預先加載了引數的函式,只有在傳遞了足夠多的引數以滿足方法簽名時才會執行。
請注意,foo_baked.lambda?returns true,所以一個 curried proc實際上是一個 lambda。這很重要,因為這意味著ArgumentError如果您超過引數的最大數量,您將得到一個。
您可以通過將 arity 引數傳遞給curry.
def foo(*args)
args.join
end
# does not execute since only 2 arguments have been supplied
foo_baked = method(:foo).curry(3).call('foo', 'bar')
# executes on the third argument
# this returns "foobar123"
foo_baked.call('123')
# this returns "foobar123234"
foo_baked.call('123', '234')
uj5u.com熱心網友回復:
您可以定義一個新方法,將不可更改的引數foo_baked包裝并作為硬編碼值傳遞:foo
def foo_baked(c)
foo("foo", "bar", c)
end
然后可以這樣呼叫:
foo_baked("123")
或者,您可以使用 Ruby 的內置#curry方法,如TonyArra 的回答中所述。這種方法更靈活,在提供足夠的引數之前回傳一個可呼叫的程序。
uj5u.com熱心網友回復:
你有幾個選擇。第一個是Zoran 的回答中概述的柯里化方法。
第二個是使用默認的位置引數。但為了做到這一點,可選引數需要在所需引數之后:
def foo_baked(a, b="foo", c="bar")
[a, b, c]
end
foo_baked(123) # => [123, "foo", "bar"]
foo_baked(123, "asd")
第三種選擇是使用關鍵字引數。這種方法的好處是引數可以按任何順序排列。您可以挑選并選擇您為其提供值的那些。
def foo_baked(b: "foo", c: "bar", a:)
[a, b, c]
end
foo_baked(a: 123) # => [123, "foo", "bar"]
foo_baked(a: 123, b: "asd") # => [123, "asd", "bar"]
最后一個選擇是結合位置引數和關鍵字引數:
def foo_baked(a, b: "foo", c: "bar")
[a, b, c]
end
foo_baked(123) # => [123, "foo", "bar"]
foo_baked(123, b: "asd") # => [123, "asd", "bar"]
這樣做的好處是仍然可以讓您使用位置引數,但是可選引數的順序無關緊要,它們永遠不會干擾位置引數
uj5u.com熱心網友回復:
您可以創建一個包裝原始方法的 lambda:
foo_baked = ->(value) { foo('foo', 'bar', value) }
foo_baked.(123) # => [123, "foo", "bar"]
請注意.執行中的其他內容。這是 ruby?? 的特殊語法,相當于:
foo_baked.call(123)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/464259.html
