2010-02-09 22 views
17

Mã này hoạt động như mong đợi (không có gì, thậm chí không tạo ra cảnh báo/lỗi):của Ruby luận lambda

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

Mã này tạo ra cảnh báo (cảnh báo: nhiều giá trị cho một tham số khối (0 trong 1)):

l = lambda {|i|} 
l.call 

Và mã này thất bại với lỗi (ArgumentError: sai số của đối số (0 2)):

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

tôi thứ nên lambda đó đòi hỏi tất cả các đối số phải được thông qua.

Và từ ví dụ thứ hai, tôi thấy rằng nó không phải là. Tại sao nó hoạt động khi chỉ có một đối số được đưa ra, và hoạt động như mong đợi (thất bại với lỗi) với nhiều hơn một đối số?

PS: ruby ​​1.8.6 (2008/08/11 patchlevel 287) [universal-darwin9.0]

UPDATE: Tôi đã kiểm tra các mẫu với ruby ​​1.9.1p376. Và nó hoạt động như mong đợi - ví dụ thứ hai cũng tạo ra lỗi. Có vẻ như đây là một tính năng của phiên bản 1.8 (hoặc < = 1.8)

Trả lời

12

Lambdas là lạ như vậy, hành vi của chúng khác nhau khi bạn có ít hơn hai đối số. Kiểm tra this article để biết thêm thông tin.

12

This script sẽ dạy cho bạn mọi thứ bạn cần biết về bao đóng trong 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

Xin lỗi, nhưng tôi không thể tìm thấy câu trả lời ở đó. Bạn có thể vui lòng chỉ? –

+0

Đã thêm một con trỏ :) – Trevoke

+0

Cảm ơn bạn!Nhưng dù sao, vẫn chưa rõ lý do tại sao hành vi đó tồn tại (chính xác - tồn tại) –

2

Khi lambda mong đợi đối số và chúng tôi không cung cấp cho chúng hoặc chúng tôi cung cấp số lượng đối số sai, ngoại lệ sẽ được ném.

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

Chúng ta có thể sử dụng phương pháp arity để tìm hiểu số lượng đối số mong đợi:

l.arity # Output: => 1 

Cũng giống như phương pháp, lambdas chấp nhận tất cả các loại sau đây của các thông số/lập luận:

  • Thông số vị trí (bắt buộc và tùy chọn)
  • Tham số splat đơn (*);
  • Thông số từ khóa (bắt buộc và tùy chọn);
  • Tham số splat kép (**);
  • Tham số chặn rõ ràng được đặt trước bằng dấu và (&).

Ví dụ sau minh họa cú pháp của lambda có nhiều loại đối số.

# 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 xử lý đối số theo cách tương tự như phương pháp. Có giải thích toàn diện về tất cả các loại tham số/đối số ở trên trong this blog post about methods.

Các vấn đề liên quan