我对smalltalk不太熟悉,但是我想做的是在初始化自己的类时覆盖另一个"new"类。
这和Class >> bindingOf:有关系吗?
编辑:
我想要实现的是:如果ObjectA调用new
,则ObjectB处理该请求。
ObjectB与ObjectA不相关。
可以仅通过更改ObjectB的实现来做到这一点吗?
编辑:我在这个故事中的ObjectB
是ObjectTracer
,我想要做的是某种类似于ObjectA
的包装器类。
我是否使用类的方法字典更改ObjectA
的new
的实现,该怎么做?
编辑:这是我想使成为可能:
| obj |
obj := ObjectA new.
obj aMethod.
真正发生的是,当
new
发送到ObjectA
时,它被ObjectB
(包装器)提供的实现所取代,就像他们的答案中提到的aka.nice和Hernan一样,ObjectB
使#doesNotUnderstand
处理打算发送给ObjectA
的消息。从本质上讲,那么我所需要的仅仅是获取
ObjectB
来替换ObjectA
的#new
吗? 最佳答案
大多数跟踪器,分析器和采样器监视系统的执行。如果您想开发一种实际上可以修改系统的跟踪器,则必须非常了解其动态性,以避免附带影响。
这是跟踪器的基本公式:
Tracers的子类从nil左右开始)
指针( super class := nil)
在Tracer的对象中
在Tracer的实例端实现#doesNotUnderstand:aMessage,例如以下模板:
doesNotUnderstand: aMessage
"trace the selector then pass the message on"
| result |
aMessage arguments size = 0
ifTrue:
[result := object perform: aMessage selector]
ifFalse:
[result := object perform: aMessage selector withArguments: aMessage arguments].
^result
在#perform:send之前的情况下,您可以访问ObjectA方法字典并将“aMessage” CompiledMethod替换为另一个。要访问某个类的方法字典,只需在某些Smalltalks中发送#methodDictionary或#>>即可。
您可以放置新的编译方法,甚至替换整个字典,因为您知道如何进行反射:
| methodDictionary |
methodDictionary := MethodDictionary new.
methodDictionary at: #basicNew put: (Object compilerClass new
compile: 'basicNew ^Point basicNew'
in: Object
notifying: nil
ifFail: []) generate.
请注意,您不需要将方法驻留在要评估的MethodDictionary中。请参阅#valueWithReceiver的发件人:参数:
最后,您发送到新对象
anObjectA := MyTracer on: ObjectA new.
anObjectA example1.
是的,您也可以将其放入ObjectA的新方法中。您最好阅读一些有关Smalltalk反射的章节,网络上有很多内容,因为Smalltalk是进行计算反射的最佳平台。
关于smalltalk - Smalltalk绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13788585/