Smalltalk 获取CompiledMethod类的实例

Smalltalk 获取CompiledMethod类的实例,smalltalk,squeak,Smalltalk,Squeak,据我所知,CompiledMethod是一个持有方法编译形式的类。每次编译方法时都会创建此类的实例。此实例保存在该方法所属的类中 我的问题是,如果我有一个方法的名称,那么我如何获得持有方法编译形式的实例,以便使用valueWithReceiver:运行该方法 是使用compiledMethodAt:selector吗?我认为我们需要更多的上下文 因为使用反射机制,您甚至可以执行以下操作: CompiledMethod allInstances select: [ :m | m selector

据我所知,CompiledMethod是一个持有方法编译形式的类。每次编译方法时都会创建此类的实例。此实例保存在该方法所属的类中

我的问题是,如果我有一个方法的名称,那么我如何获得持有方法编译形式的实例,以便使用valueWithReceiver:运行该方法


是使用compiledMethodAt:selector吗?

我认为我们需要更多的上下文

因为使用反射机制,您甚至可以执行以下操作:

CompiledMethod allInstances select: [ :m | m selector = #asString ]
这将为您提供带有选择器
asString
的所有方法。但是这个动作很奇怪

您还可以使用
#detect:
而不是
#select:
来查找单个方法

如果需要评估所有找到的方法,可以使用:

CompiledMethod allInstances
    select: [ :m | m selector = #asString ]
    thenDo: [ :m | m valueWithReceiver: aReceiver ]
另外,如果您对一个层次结构的方法感兴趣,可以这样做

YourClass withAllSubclassesDo: [ :class |
    class
        compiledMethodAt: #selector
        ifPresent: [ :method | method valueWithReceiver: aReceiver ]
        ifAbsent:  [ "do nothing" ]

如果您不确定发送消息的答案是什么,您可以随时询问结果类。打印:

(Behavior compiledMethodAt: #compiledMethodAt:) class
在本例中,它是
CompiledMethod
——正是您所寻找的。
是的,您可以使用带有
valueWithReceiver:

的编译方法。您可以让虚拟机为您查找该方法并运行它,表达式如下:

object perform: selector

虚拟机将在对象的类中查找与选择器关联的方法,并以对象作为接收器运行它。此消息有类似的形式用于传递参数。

值得一试:)我正在尝试。。只希望我没有做错它可以工作:-)我已经使用compiledMethodAt来获取已编译方法的实例。。。谢谢你,Uko..我实际上需要得到所有同名的方法(在继承链中),所以我尝试了你的方法:compiledMethodAllInstancesSelect:[:m | m selector=#asString]。。但它不起作用。。。m是编译方法吗?我可以在这个块中运行每个m吗?@Shiran我已经添加了如何评估所有找到的方法的说明和一个HierarchyThank的选项。。将很快尝试:-)因此,通过这样做,它将运行与选择器关联的所有方法?我需要运行已覆盖的方法以及新方法。它将运行虚拟机的查找过程找到的单个方法。查找从接收方的类开始,然后通过该类的超类、类对象继续进行。如果未找到任何方法,它将向MessageNotUnderstanding异常发送信号。要运行重写的方法,请使用上面建议的valueWithReceiver:技术。