Smalltalk 中的函数对象(或执行没有“value:”的块)

发布于 2024-09-30 17:30:01 字数 340 浏览 5 评论 0原文

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

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

其中 reduceapplyToAlltranspose 是对象,而 + >、* 和两个数组是传递给发送给这些对象的匿名消息的参数。是否可以使用块来实现相同的效果? (但没有显式使用 value:)。

Is it possible to send an anonymous message to an object? I want to compose three objects like this (think FP):

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

where reduce, applyToAll and transpose are objects and +, * and the two arrays are arguments passed to anonymous messages sent to those objects. Is it possible to achieve the same using blocks? (but no explicit usage of value:).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷爱 2024-10-07 17:30:01
aRealObject reduceMethod: +; 
            applyToAll: *; 
            transpose: #(#(1 2 3) #(4 5 6));
            evaluate

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

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

would work when aRealObject has defined the right methods. Where do you need a block?

下壹個目標 2024-10-07 17:30:01

您正在寻找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)

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

You are looking for doesNotUnderstand:. If reduce is an object that does not implement + but you send it anyway, then instead its doesNotUnderstand: method will be invoked. Normally it just raises an error. But you can override the default, and access the selector + and the other argument and do whatever you like with them.

For simplicity, create a class Reduce. On its class side, define the method:

doesNotUnderstand: aMessage
    ^aMessage argument reduce: aMessage selector

Then you can use it like this:

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

which in a Squeak workspace answers 32, as expected.

It works because * is already implemented for Collections with suitable semantics.

Alternatively, add a class ApplyToAll with this class-side method:

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

and also add this method to SequenceableCollection:

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

Then you can write

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

which is pretty close to your original idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文