2010-11-08 27 views
6

Có thể gửi tin nhắn ẩn danh tới một đối tượng không? Tôi muốn soạn ba đối tượng như thế này (nghĩ FP):Các đối tượng chức năng trong Smalltalk (hoặc thực hiện các khối không có `giá trị:`)

" find inner product " 
reduce + (applyToAll * (transpose #(1 2 3) #(4 5 6))) 

nơi reduce, applyToAlltranspose là những đối tượng và +, * và hai mảng là đối số được truyền đến thông điệp nặc danh gửi đến các đối tượng. Có thể đạt được cùng một khối sử dụng không? (nhưng không sử dụng rõ ràng là value:).

Trả lời

5
+0

nhưng trong khi bạn có thể muốn làm điều đó và có thể bạn không nên. Ít nhất là không giải quyết vấn đề này. –

5
aRealObject reduceMethod: +; 
      applyToAll: *; 
      transpose: #(#(1 2 3) #(4 5 6)); 
      evaluate 

sẽ hoạt động khi aRealObject đã xác định đúng phương pháp. Bạn cần một khối ở đâu?

3

Bạn đang tìm kiếm doesNotUnderstand:. Nếu reduce là một đối tượng không triển khai + nhưng bạn vẫn gửi nó, thì phương thức doesNotUnderstand: của nó sẽ được gọi. Thông thường nó chỉ gây ra lỗi. Nhưng bạn có thể ghi đè lên mặc định và truy cập bộ chọn + và đối số khác và làm bất cứ điều gì bạn thích với chúng.

Để đơn giản, hãy tạo lớp học Reduce. Về phía các lớp học, xác định phương pháp:

doesNotUnderstand: aMessage 
    ^aMessage argument reduce: aMessage selector 

Sau đó, bạn có thể sử dụng nó như thế này:

Reduce + (#(1 2 3) * #(4 5 6)) 

đó trong một không gian làm việc Squeak trả lời 32, như mong đợi.

Nó hoạt động vì * đã được triển khai cho Bộ sưu tập có ngữ nghĩa phù hợp.

Ngoài ra, thêm một lớp ApplyToAll với phương pháp đẳng cấp bên này:

doesNotUnderstand: aMessage 
    ^aMessage argument collect: [:e | e reduce: aMessage selector] 

và cũng thêm phương pháp này để SequenceableCollection:

transposed 
    ^self first withIndexCollect: [:c :i | self collect: [:r | r at: i]] 

Sau đó, bạn có thể viết

Reduce + (ApplyToAll * #((1 2 3) #(4 5 6)) transposed) 

đó là khá gần với ý tưởng ban đầu của bạn.

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