不,#bindingOf: 与编译方法有关。
可通过多种方法访问的变量,如全局变量、类变量或池变量,通过在方法文字中存储相同的绑定来共享。绑定是一种关联,其键是变量名,值是变量值。
当您的代码使用变量时,该方法将#value 发送到引擎盖下的绑定,并且当您将值存储到变量中时,它会发送#value:
但是请注意,根据 Smalltalk 的风格,这些操作可能会在字节码中进行优化,并替换为直接访问绑定的第二个实例变量(值)。
因此编译器需要检索 bindingOf: aSymbol 才能访问任何共享变量,其中 aSymbol 是变量的名称。因为变量访问的范围取决于类(只有一个类及其子类可以访问类变量......),所以会查询该方法编译到的类以获取该信息。
如果你想覆盖 YourClass 中的实例创建,只需在类侧覆盖#new(我们说 YourClass class>>#new)。如果您使用 Squeak/Pharo 方言,大多数情况下,您可以通过在实例端 (YourClass>>#initialize) 重写 #initialize 来实现特定的实例化,因为 #new 将调用 #initialize。
编辑
如果您想使用 ObjectTracer 捕获 #new 到 ObjectA 的发送,您可以执行以下操作:
| theTrueObjectA |
theTrueObjectA := ObjectA.
[Smalltalk globals at: #ObjectA put: (ObjectTracer on: ObjectA).
"insert the code you want to test here"
ObjectA new]
ensure: [Smalltalk globals at: #ObjectA put: theTrueObjectA].
EDIT2最后一句可以替换为ensure: [ObjectA xxxUnTrace]
然而,现代的 squeak 调试器是侵入性的,它本身会向 ObjectTracer 发送许多消息,导致其他调试器弹出......您应该首先打开一个 Preferences 窗口并禁用 logDebuggerStackToFile。
请注意,所涉及的机制是消息#doesNotUnderstand:由对象在它不理解消息时发送。ObjectTracer 覆盖 #doesNotUnderstand: 以弹出调试器。
你可以继承 ProtoObject 来安装你自己的 #doesNotUnderstand: 处理(就像只是在转录或文件中写一些东西)。
另请注意,ObjectTracer #inheritsFrom: ProtoObject 和 ProtoObject 本身 #respondsTo: 许多消息不会被 ProtoObject>>#doesNotUnderstand 捕获:
最后说明:我在上面用#表示可以理解的消息。
编辑 3:一种可能的解决方案是定义一种新的 ObjectTracer,其中包含两个实例变量 tracedObject 和 messageMapping 以及此实例创建:
MessageInterceptor class>>on: anObject interceptMessages: aDictionary
"Create an interceptor intercepting some messages sent to anObject.
aDictionary keys define message selectors that should be intercepted.
aDictionary values define block of code that should be evaluated in place.
These blocks always take one argument for passing the traced Object,
plus one argument per message parameter.
snip..."
MessageInterceptor>>doesNotUnderstand: aMessage
mapping := messageMapping at: aMessage selector
ifAbsent:
["We don't intercept this message, let the tracedObject handle it"
^aMessage sendTo: tracedObject].
^mapping valueWithArguments: {tracedObject} , aMessage arguments
例如,您可以这样使用它:
| interceptor |
interceptor := MessageInterceptor on: ObjectA interceptMessages:
({#new -> [:class | ObjectTracer on: class new]} as: Dictionary).
[Smalltalk globals at: #ObjectA put: interceptor.
"insert the code you want to test here"
ObjectA new yourself]
ensure: [interceptor xxxUnTrace].