6

是否可以向对象发送匿名消息?我想像这样组成三个对象(想想 FP):

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

其中reduce,applyToAlltranspose是对象 和+,*两个数组是传递给发送到这些对象的匿名消息的参数。是否可以使用块来实现相同的目标?(但没有明确使用value:)。

4

3 回答 3

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

当 aRealObject 定义了正确的方法时会起作用。你在哪里需要一个块?

于 2010-11-08T08:35:40.680 回答
3

您正在寻找doesNotUnderstand:. 如果reduce是一个没有实现的对象,+但你还是发送了它,那么它的doesNotUnderstand:方法将被调用。通常它只会引发错误。但是您可以覆盖默认值,并访问选择器+和其他参数,并对它们做任何您喜欢的事情。

为简单起见,创建一个类Reduce。在其类方面,定义方法:

doesNotUnderstand: aMessage
    ^aMessage argument reduce: aMessage selector

然后你可以像这样使用它:

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

正如预期的那样,在 Squeak 工作区中回答 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)

这与您最初的想法非常接近。

于 2010-11-18T14:07:14.217 回答