Smalltalk中的函数对象(或执行没有`value:`的块)
问题描述:
是否可以向对象发送匿名消息?我想组成三个对象是这样的(认为FP):Smalltalk中的函数对象(或执行没有`value:`的块)
" find inner product "
reduce + (applyToAll * (transpose #(1 2 3) #(4 5 6)))
其中reduce
,applyToAll
和transpose
是对象和+
,*
和两个数组传递给发送到这些对象匿名的消息参数。是否有可能实现相同的使用块? (但没有明确使用value:
)。
答
aRealObject reduceMethod: +;
applyToAll: *;
transpose: #(#(1 2 3) #(4 5 6));
evaluate
当aRealObject定义了正确的方法时会工作。你在哪里需要一个街区?
答
您正在寻找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)
这非常接近你原来的想法。
虽然你可能想这样做,也可以,也许你不应该。至少不能解决这个问题。 – 2010-11-09 11:36:04