2009-08-07 46 views
21

Tôi có một vài câu hỏi về phương pháp, thủ tục và khối của Ruby khiến tôi khá kỳ quặc. Chúng không quá nhiều về cú pháp hay hàm như logic đằng sau các quyết định được đưa ra.Phương pháp Ruby, Proc và sự nhầm lẫn khối

Câu hỏi 1:

Tại sao nó rằng khối có thể được truyền cho phương pháp (ví dụ mỗi) nhưng họ không thể được gán cho một biến?

Tôi biết bạn có thể chuyển chúng xung quanh trong các thủ tục, ví dụ: p = Proc.new {...} (truy cập với &p), nhưng không có ý nghĩa nhiều khi làm cho lập trình viên trải qua các phương tiện này.

Câu hỏi 2:

Tại sao lại có sự khác biệt giữa các phương pháp và thủ tục?

Ví dụ, tôi có thể hoàn thành nhiệm vụ xác định một hàm và gọi hàm trong hai cách sau:

def square(x) 
    x**2 
end 

square(3) 
=> 9 

hoặc

square = lambda {|x| x**2} 
square.call(3) 
=> 9 

Tại sao sự khác biệt? Trong Python ví dụ, cả hai định nghĩa một hàm theo cách tiêu chuẩn và bởi square = lambda x: x**2 thực hiện cùng một nhiệm vụ tạo hàm và gán nó cho square.

Trả lời

20

Câu hỏi 1: Khối không phải là đối tượng, chúng là cấu trúc cú pháp; đây là lý do tại sao chúng không thể được gán cho một biến. Đây là đặc quyền dành riêng cho các đối tượng.

Câu hỏi 2: Phương pháp không phải là đối tượng, vì vậy họ không thể nhận tin nhắn. Ngược lại, procs và lambdas là các đối tượng, vì vậy chúng không thể được gọi như các phương thức, nhưng phải nhận được một thông báo cho chúng trả về một giá trị trên cơ sở các tham số được truyền với thông điệp.

Procs và Lambdas là các đối tượng, để họ có thể nhận được thông báo call và được gán cho tên. Tóm lại, nó là một đối tượng khiến procs và lambdas cư xử theo cách bạn thấy kỳ quặc. Phương thức và khối không phải là đối tượng và không chia sẻ hành vi đó.

+5

Ruby tuyên bố mọi thứ đều là một đối tượng. Các khối phải là các đối tượng để phù hợp với điều đó và chúng có thể được chuyển thành các đối số, vì vậy chúng chắc chắn hoạt động giống như các đối tượng theo một số cách. – rpjohnst

+6

Các khối có thể được thực hiện để hoạt động như các đối tượng thông qua việc tạo ra một đối tượng đại diện cho chúng, một proc hoặc một lambda. Không có thiết bị đó, chúng chỉ là cấu trúc cú pháp. – Pinochle

+0

Có các đối tượng khối - đó là mục đích của lambda {bất cứ điều gì}. – Chuck

4

Phương pháp là các phương thức - tức là, chúng là những hành động mà một đối tượng có thể thực hiện để phản hồi lại các tin nhắn. Chúng không có chức năng.

Chặn đang đóng - chúng là các hàm đóng trên phạm vi bao quanh. Họ không khái niệm "thuộc về" một đối tượng nhất định.

Trong một số ngôn ngữ, phương pháp chỉ đơn thuần là các hàm là thành viên của một đối tượng, nhưng Ruby không xem chúng theo cách này. Việc tách một phương thức khỏi đối tượng sở hữu của nó giống như phẫu thuật hơn là gán đơn giản. Ruby lấy mô hình hướng đối tượng của nó từ Smalltalk, ông nội của OO hiện đại.

5

Đối với một số mức độ tối thiểu, phương pháp đối tượng:

class ABC 
    def some_method 
    end 
end 
ABC.instance_method(:some_method) #=> #<UnboundMethod: ABC#some_method> 

Tiếp tục vào đó, có một built-in Class: Phương pháp, như tài liệu here.

Xem thêm này: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

bừa bãi <bseg>, nó dường như khá chịu ra tất cả mọi thứ-là-một-đối tượng điều. Trong trường hợp đặc biệt này, nó chỉ xuất hiện để có thêm một chút đào để xem.

(Tôi thực sự phải nỗ lực để hiểu điều này tốt hơn: Tôi bắt đầu nghĩ rằng đó là nền tảng để hiểu sâu hơn.)

+0

Các phương pháp dường như lấy tính khách quan của chúng từ các trường hợp của 'Proc'. Trong tài liệu 'ri' cho' Method', từ 'method' không được sử dụng trong phần giải thích, nhưng 'proc' là. Hai lớp nhận được cùng một thông điệp, nhưng sự khác biệt là cách chúng được gọi và thực tế là các phương thức được định nghĩa trong không gian tên của đối tượng khác, trong đó procs cần nhận 'call'method để được gọi và tồn tại (persist, as Tôi đã nói trước đó) một cách độc lập với các vật thể khác. – Pinochle

+0

Ahh, một sự khác biệt ... 'Phương thức' không nhận được thông điệp' mới', nơi 'Proc' thực hiện. Nếu các phương thức là các đối tượng, chúng không phải là các đối tượng theo nghĩa đầy đủ ('đầy đủ' có nghĩa là có tất cả các đặc tính mà chúng ta thường thấy trong các đối tượng). – Pinochle

+0

Liên kết wikibooks hữu ích. Cảm ơn. – David