Smalltalk 从发送方上下文获取链的接收方

Smalltalk 从发送方上下文获取链的接收方,smalltalk,callstack,pharo,Smalltalk,Callstack,Pharo,想象一下,我有这样一种方法 someMethod ^ instVar class getProperty 我能以某种方式实现getProperty方法吗 getProperty thisContext sender ... 获取要向其发送类的对象?我是instVar的值,但不知道它是一个实例变量,在其他一些情况下可能是一个参数或一个文本。我看不到任何明显的东西,instVar不再在执行堆栈上,它已被消息“class”的返回值替换 也许您可以欺骗并检测“class getPrope

想象一下,我有这样一种方法

someMethod

  ^ instVar class getProperty
我能以某种方式实现
getProperty
方法吗

getProperty

  thisContext sender ...

获取要向其发送
的对象?我是
instVar的值,但不知道它是一个实例变量,在其他一些情况下可能是一个参数或一个文本。

我看不到任何明显的东西,instVar不再在执行堆栈上,它已被消息“class”的返回值替换


也许您可以欺骗并检测“class getProperty”链的所有发送者,以执行一些特殊的操作,例如替换为“MyAnalyzer getClassPropertyOf:instVar”。听起来很邪恶。

你能按如下方式重构某个方法吗

someMethod

  ^ instVar class getPropertyOf: instVar

在回答
类时,您可以插入插槽以返回包装器或代理。代理会知道插槽中的对象。

这很可怕,可能不会在所有情况下都起作用,但如果您必须这样做,可能会为您提供一个起点(同时也是Smalltalk中可能的反射率级别的一个很好的演示):


你想干什么?莱安德罗说的。这不是你的方法吗,也就是说,你不知道
instVar
是否是一个实例变量吗?你想做某种形式的IoC吗?遗憾的是,不,这就是我想遍历上下文的原因,因为我无法更改现有代码,而且在系统中有很多类似的用法。如果instVar不是实例变量,它能工作吗?不,不幸的是不能。我想我还是提一下,以防总是涉及实例变量。
getProperty 

    | sender message receiver |

    sender := thisContext sender.
    message := sender method abstractBytecodeMessageAt: (sender pc - 3).

    message selector = #pushReceiverVariable: ifTrue: [receiver := sender receiver instVarAt: (message arguments first + 1)].
    message selector = #pushTemporaryVariable: ifTrue: [receiver := sender tempAt: (message arguments first + 1)].
    message selector = #pushConstant: ifTrue: [receiver := message arguments first].

    receiver isNil ifTrue: [self error: 'unknown'].

    ^receiver