2010-11-08 21 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) 

这非常接近你原来的想法。