2012-12-12 15 views
6

Tôi gặp khó khăn tìm hiểu những gì làm cho các hành vi sau đây có thể (lấy từ cuốn sách ruby ​​cuốc):Lambda Behavior

def power_proc_generator 
    value = 1 
    lambda {value += value} 
end 

power_proc = power_proc_generator 

3.times {puts power_proc.call} # => 2,4,8 
3.times {puts power_proc_generator.call()} # => 2,2,2 

Tôi không thấy như thế nào "power_proc" đối tượng cho phép giá trị để tiếp tục tăng gấp đôi như Tôi sẽ giả định (sai dường như) rằng mỗi cuộc gọi sẽ gán lại giá trị cho 1.

Câu hỏi của tôi là tại sao "3.times {puts power_proc.call}" kết quả "2,4,8" chứ không phải "2, 2,2 "?

+0

Cố gắng nêu câu hỏi của bạn dưới dạng câu hỏi, vì vậy sẽ ít nhầm lẫn hơn. – knownasilya

+0

Xin lỗi về điều đó tôi đã làm rõ với một câu hỏi thực tế. – Discorick

Trả lời

5

power_proc_generator trả về một lambda sử dụng (và sửa đổi) giá trị của một biến trong phạm vi xung quanh. Điều này được gọi là đóng cửa - hàm trả về "đóng" trên giá trị của biến số value. Vì vậy, mỗi khi bạn gọi hàm trả về, nó sẽ nhân một số value cho hai. Phần quan trọng là value nằm giữa các cuộc gọi đến power_proc.call, vì vậy, bạn đang sửa đổi biến hiện tại.

Ngoài ra, để xây dựng trên sự khác biệt giữa in power_proc_generatorpower_proc.call-power_proc_generator trả về một chức năng mới mỗi lần nó được gọi, đó là lý do tại sao bạn không bao giờ nhìn thấy value được tăng lên. power_proc.call, mặt khác, tiếp tục gọi cùng chức năng nhiều lần.

+0

Được rồi, vì vậy tôi nghĩ vấn đề của tôi ít hơn về hiểu lambdas và nhiều hơn nữa về việc không thực sự hiểu được bao đóng, vì vậy các bao đóng mang trạng thái biến gần đây nhất, cuộc gọi hàm không đối tượng sẽ chỉ đánh giá lại từ đầu. – Discorick

2

power_proc_generator trả về một lambda bao gồm một bao đóng chứa giá trị 'biến'. Vì vậy, biến đó bị treo xung quanh từ một power_proc.call sang bước kế tiếp.