2010-11-08 66 views
6

是否可以向對象發送匿名消息?我想組成三個對象是這樣的(認爲FP):Smalltalk中的函數對象(或執行沒有`value:`的塊)

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

其中reduceapplyToAlltranspose是對象和+*和兩個數組傳遞給發送到這些對象匿名的消息參數。是否有可能實現相同的使用塊? (但沒有明確使用value:)。

回答

5
+0

雖然你可能想這樣做,也可以,也許你不應該。至少不能解決這個問題。 – 2010-11-09 11:36:04

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

當aRealObject定義了正確的方法時會工作。你在哪裏需要一個街區?

3

您正在尋找doesNotUnderstand:。如果reduce是一個不實現+的對象,但是您仍然發送該對象,則會調用它的doesNotUnderstand:方法。通常它只會引發錯誤。但是您可以覆蓋默認值,並訪問選擇器+和另一個參數,並對它們進行任何您喜歡的操作。

爲了簡單起見,創建一個類Reduce。在同級車側,定義方法:

doesNotUnderstand: aMessage 
    ^aMessage argument reduce: aMessage selector 

然後你可以使用它像這樣:

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

其在佳樂工作區回答32,符合市場預期。

它的工作原理是因爲*已經爲具有合適語義的集合實現。

另外,添加一個類ApplyToAll這一類端的方法:

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

,並添加這個方法來SequenceableCollection

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

然後,你可以寫

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

這非常接近你原來的想法。