Smalltalk绑定

itc*_*y23 2 smalltalk squeak pharo

我对smalltalk不是很熟悉,但是当我初始化自己的类时,我正在尝试做的是覆盖另一个类'new'.这与Class >> bindingOf有什么关系:?

编辑:

我想要实现的是:如果ObjectA调用new,则ObjectB处理请求.
ObjectB与ObjectA无关.
这可以通过仅改变ObjectB的实现来完成吗?

编辑:我ObjectB在这个故事中是一个ObjectTracer和我想要它做的是表现得像一个包装类ObjectA.我是否更改ObjectAnew使用类的方法字典的实现,以及如何完成?

编辑:这是我想要的:

| obj |
obj := ObjectA new.
obj aMethod.
Run Code Online (Sandbox Code Playgroud)

而到底发生了什么的是,当new被送到ObjectA,它与所提供的实施方案替换的ObjectB(包装)和像aka.nice和埃尔南在他们的答案中提到,ObjectB使#doesNotUnderstand处理用于消息ObjectA.
从本质上讲,是有可能,然后,所有我需要的是让ObjectB更换ObjectA#new

Her*_*nán 5

大多数跟踪器,分析器和采样器监视系统的执行.如果你想开发一个实际修改系统的跟踪器,你必须非常清楚它的动态以避免附带效应.

这是示踪剂的基本公式:

  • 您将使用Tracer(anObjectB)包装anObjectA
  • 使用"object"实例变量创建一个Tracer类(大多数Tracers子类来自nil左右)
  • 在Tracer的类侧实现#initialize删除超类指针(超类:= nil)
  • 在Tracer的类侧实现#on:anObjectA,用于在Tracer的对象中存储aObjectA

在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
Run Code Online (Sandbox Code Playgroud)

在您的情况下,在#perform:发送之前,您可以访问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.
Run Code Online (Sandbox Code Playgroud)

请注意,您不需要驻留在MethodDictionary中的方法来进行评估.查看#valueWithReceiver:arguments的发件人:

最后,您将发送给您的新对象

anObjectA := MyTracer on: ObjectA new.
anObjectA example1.
Run Code Online (Sandbox Code Playgroud)

是的,你也可以把它放在ObjectA的新方法中.你最好阅读一些有关Reflection in Smalltalk的章节,网上有很多内容,因为Smalltalk是进行计算反射的最佳平台.