gpt4 book ai didi

reflection - Squeak 中的拦截消息

转载 作者:行者123 更新时间:2023-12-04 18:45:08 27 4
gpt4 key购买 nike

我试图更好地理解 Smalltalk 中的反射。我正在使用最新版本的 Squeak (v4.3)。我想拦截发送到我的一个类的实例的每条消息。我假设我可以覆盖方法 ProtoObject>>withArgs:executeMethod但 Stéphane Ducasse 向我解释说,出于性能原因,没有使用这种方法(这是我自己对他的回答的总结)。我应该覆盖哪种方法/如何拦截发送的消息?

这是我尝试的代码:

Object subclass: #C
instanceVariableNames: 'i'
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.

C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.

C compile: 'withArgs: someArgs executeMethod: aMethod
Transcript show: ''Caught: ''.
^ super withArgs: someArgs executeMethod aMethod.'.

C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.

C compile: 'i: anInt
i := anInt.'.

o := C newWithi: 42.
o foo: 'This is foo: '.

执行这整段代码会产生:
This is foo: 42

当我想要:
Caught: This is foo: 42

最佳答案

没有内置方法可以拦截此类对象的消息。我们通常使用两种方法来完成这种技巧。

首先,您可以创建一个响应doesNotUnderstand: 的包装器对象。该对象的父类(super class)通常为 nil,因此它不会从 Object 继承任何实例方法。 doesNotUnderstand: 处理程序会将其所有消息委托(delegate)给目标对象。它可以选择在调用之前和之后执行代码。所有对原始对象的引用现在都将指向新的“代理”对象。发给 self 的消息不会被拦截,代理需要测试返回 self 的对象并将返回的对象更改为代理。

第二种方法是使用一种称为 Method Wrappers 的机制。方法包装器允许您将一组类中的所有方法替换为在调用原始方法之前和之后执行一些其他操作的方法。这种方法可以提供相当完美的结果并拦截所有消息,包括发送给自己的消息。

MethodWrappers 可用于 VisualWorks 和 VASmalltalk。我相信它也适用于 Squeak和法罗,但我不积极。

关于reflection - Squeak 中的拦截消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15975340/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com