2009-05-27 19 views
8

Trong ví dụ bên dưới, tại sao chúng ta nói "k.send: hello" thay vì "k.receive: hello" nếu, as stated elsewhere, k thực sự là người nhận?"k.send: hello" - nếu k là "người nhận", người gửi là ai?

âm thanh như k là người gửi chứ không phải người nhận.

Khi chúng tôi nói "k.send: hello" đang gửi, nếu không k?

(Bạn bối rối như tôi?)

class Klass 
    def hello 
    "Hello!" 
    end 
end 
k = Klass.new 
k.send :hello #=> "Hello" 
k.hello   #=> "Hello" 

Trả lời

6

Bất kỳ đối tượng nào chứa mã này đều gửi tin nhắn - có lẽ là chính. Hãy nhìn vào nó với các đối tượng rõ ràng hơn và thông điệp đi qua bình thường.

class Person 
    attr_accessor :first_name, :last_name 
    def initialize(first_name, last_name) 
    @first_name, @last_name = first_name, last_name 
    end 
    def marry(other) 
    self.last_name = other.last_name 
    end 
end 

bob = Person.new('Bob', 'Smith') 
patty = Person.new('Patricia', 'Johnson') 

patty.marry bob 

Trong dòng cuối cùng của mã này, chính là gửi marry để patty, và patty lần lượt gửi mình last_name= và gửi bob last_name.

+0

Làm thế nào để chúng ta biết "chính là gửi kết hôn với patty" hơn là "patty đang gọi kết hôn với chính mình"? – lorz

+1

Patty đang thực hiện phương thức kết hôn - để đáp lại thông điệp của chúng tôi. Chúng ta có thể xóa phương thức kết hôn và thực hiện method_missing và chúng ta vẫn thấy và có thể trả lời tin nhắn mặc dù không còn phương thức kết hôn nữa để gọi. – Chuck

+0

Xin lỗi tôi rất chậm hiểu. Tôi vẫn không hiểu lý do tại sao điểm cuối cùng của bạn chứng minh rằng chính là nguồn gốc của thông điệp chứ không phải là patty. – lorz

7

Trong Smalltalk, tất cả mọi thứ là một đối tượng. "Người gửi" là đối tượng là chủ sở hữu của phạm vi nơi thư bắt nguồn (tức là con trỏ "này" hoặc "tự").

Như trước đây, Ruby thừa hưởng khái niệm này. Trong điều kiện ít trừu tượng hơn, nếu tôi gửi cho bạn một lá thư, tôi là "người gửi" (nó đến từ văn phòng của tôi), và bạn là "người nhận" (địa chỉ ở mặt trước là của bạn). Vì vậy, tôi muốn viết foo.send myLetter: Bạn, foo, nhận được lá thư của tôi. Người gửi ngầm, chủ sở hữu mã thực hiện "đăng".

+0

Hmmm. Vẫn còn thực sự bối rối về điều này. Tôi đến từ Java. Vì vậy, tôi "gọi" một phương pháp trên một đối tượng. Điều đó khác với khái niệm gửi/nhận này hay chỉ là thuật ngữ khác? – lorz

+0

Chỉ là thuật ngữ khác: Để "gọi", hãy đọc "gửi tin nhắn". Đối với "Tôi đã được gọi", đọc "Tôi là người nhận" –

+1

Nó không chỉ là thuật ngữ khác nhau. Bạn có thể gửi tin nhắn không có phương thức tương ứng. Bạn không thể gọi một phương thức không tồn tại. – Chuck

2

Tôi có thể thấy nơi bạn đang bối rối, nhưng vấn đề phần lớn là ngữ nghĩa. Đối số của bạn là phương thức send thực sự là receive, vì knhận được một thông báo (ví dụ: k.receive :hello). Bằng tiếng Anh đơn giản, bạn đọc k.send :hello là "k gửi thư 'hello' (cho ai?)", Thay vì "k được gửi tin nhắn" hello "".

Một thể đổi tên phương pháp "tiếp nhận", nhưng đó cũng là một chút của một cái tên nhầm lẫn, bởi vì k thể không nhận được thông báo - k có thể không đáp ứng với thông điệp, k có thể chọn để bỏ qua nó, hoặc k có thể chọn chuyển nó cho một đối tượng khác. Trong Ruby (và Smalltalk, ảnh hưởng đến Ruby), các phương thức giống như yêu cầu để làm điều gì đó, thay vì lệnh để thực hiện.

+1

Có, bạn đã hiểu nhầm lẫn ngữ nghĩa của tôi. Nhưng tôi không hiểu ý của bạn - "k có thể không nhận được tin nhắn - k có thể không trả lời tin nhắn, k có thể chọn bỏ qua nó, hoặc k có thể chọn chuyển nó cho một đối tượng khác" Làm sao có thể k bỏ qua tin nhắn? – lorz

+1

Trong Smalltalk, chính xác cùng một phương pháp được gọi là thực hiện :, mà tôi nghĩ là một tên tốt hơn cho nó. – Chuck

+0

@ lorz: Một số lý do: k có thể không triển khai phương thức 'hello' hoặc có thể chọn không thực hiện gì trong quá trình triển khai; hoặc nó có thể truyền thông điệp cho một đối tượng khác. Lựa chọn "bỏ qua" của tôi có thể kém (kể từ trong, ví dụ: Java, bạn có thể triển khai phương thức mà không làm gì cả). @ Chuck: Tôi đồng ý. Tôi nghĩ rằng khuôn khổ Cocoa sử dụng tên performSelector :, quá. – mipadi

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