2010-02-09 105 views
17

此代碼按預期方式工作(不執行任何操作,即使不產生警告/錯誤):紅寶石拉姆達參數

l = lambda {|i|} 
l.call(1) 

此代碼生成警告(警告:多個值塊參數(0 1) ):

l = lambda {|i|} 
l.call 

而這個代碼失敗,錯誤(引發ArgumentError:錯誤的參數數目(0爲2)):

l = lambda {|i, y|} 
l.call 

我個應該要求lambda需要所有參數才能通過。

而從第二個例子中我發現事實並非如此。爲什麼它只有一個參數給出,並按預期工作(失敗,錯誤)與多個參數?

PS:紅寶石1.8.6(2008-08-11 PATCHLEVEL 287)[萬向darwin9.0]

更新:我已經檢查了這些樣品用紅寶石1.9.1p376。它按預期工作 - 第二個例子也會產生錯誤。看起來這是1.8版本的一個特性(或者< = 1.8)

回答

12

蘭巴達斯很奇怪,他們的行爲是不同的,當你有少於兩個參數。檢查this article欲知更多信息。

12

This script會告訴你一切你需要知道的關於Ruby中的閉包。

# So, what's the final verdict on those 7 closure-like entities?   
# 
#              "return" returns from closure 
#         True closure? or declaring context...?   Arity check? 
#         --------------- ----------------------------- ------------------- 
# 1. block (called with yield)  N    declaring      no 
# 2. block (&b => f(&b) => yield) N    declaring      no 
# 3. block (&b => b.call)   Y except return declaring      warn on too few 
# 4. Proc.new      Y except return declaring      warn on too few 
# 5. proc         <<< alias for lambda in 1.8, Proc.new in 1.9 >>> 
# 6. lambda       Y    closure       yes, except arity 1 
# 7. method       Y    closure       yes 
+0

對不起,但我找不到答案。你能指點一下嗎? –

+0

加了一個指針:) – Trevoke

+0

謝謝!但無論如何,它仍然不清楚爲什麼這樣的行爲存在(是正確的 - 存在) –

2

當一個lambda需要參數並且我們不提供它們,或者我們提供了錯誤數量的參數時,會引發異常。

l = lambda { |name| puts "Today we will practice #{name} meditation." } 
l.call 
ArgumentError: wrong number of arguments (given 0, expected 1) 

我們可以使用元數法,找出預期參數的數量:

l.arity # Output: => 1 

就像方法,lambda表達式接受所有的下列類型的參數/論點:

  • 位置參數(必需和可選)
  • 單個參數(*);
  • 關鍵字參數(必需和可選);
  • Double splat parameter(**);
  • 以「&」符號前綴的顯式塊參數(&)。

以下示例說明採用多種類型參數的lambda的語法。

# Stabby syntax 
l = -> (cushion, meditation="kinhin", *room_items, time:, posture: "kekkafuza", **periods, &p) do 
    p.call 
end 

# Regular syntax 
l = lambda do |cushion, meditation="kinhin", *room_items, time:, posture:  "kekkafuza", **periods, &p| 
    p.call 
end 

l.call("zafu", "zazen", "zabuton", "incense", time: 40, period1: "morning", period2: "afternoon") { puts "Hello from inside the block, which is now a proc." } 

Output: 
Hello from inside the block, which is now a proc. 

Lambdas以與方法相同的方式處理參數。上述所有參數/參數類型都有詳細的說明,其中包括this blog post about methods.