从发件人上下文获取链的接收者

时间:2016-09-09 19:54:49

标签: smalltalk callstack pharo

想象一下,我有一个像

这样的方法
someMethod

  ^ instVar class getProperty

我能否以某种方式实现getProperty方法

getProperty

  thisContext sender ...

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

4 个答案:

答案 0 :(得分:1)

我没有看到任何明显的东西,instVar已经不在执行堆栈上了,它被消息' class'的返回值所取代。

也许你可以欺骗和监督所有发送者的getProperty'链做一些特别的事情,比如替换为' MyAnalyzer getClassPropertyOf:instVar'。这听起来很邪恶。

答案 1 :(得分:1)

这很糟糕,可能在所有情况下都不会起作用,但如果您必须这样做,可能会给您一个起点(并且也很好地展示了Smalltalk中可能的反射率水平):< / p>

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

答案 2 :(得分:0)

你能按如下方式重构someMethod吗?

someMethod

  ^ instVar class getPropertyOf: instVar

答案 3 :(得分:0)

您可以检测插槽以在回答class时返回包装器或代理。代理将知道插槽所持有的对象。