Pharo Smalltalk - 如何检查消息是否符合另一个对象 Class 中定义的协议?

Pharo Smalltalk - How can I check if a message conforms to a protocol defined in another object's Class?

我正在查看此表单 Objective-C 背景,请保持温和。实验看起来像这样:

Object1 有一个名为 delegate 的实例变量。

Object1 收到一条消息,然后继续检查委托是否实现了特定协议(其名称事先已知),如果实现了,则它检查消息是否在协议的实现方法中。然后它决定如何与委托交互等等。

在Objective-C中必须定义明确的协议,通常存储在不同的文件中,并由编译器检查是否符合协议。在 Pharo 中,我似乎无法找到如何检查此类信息,即使浏览器有一整列专门用于协议,而且除了分组方法之外,它们似乎做的很少。

代理在Ghost/Marea and the original Smalltalk wrappers to the rescue I'm not sure the proxies have been updated for the latest Pharo version. Latest ghost version seems to be here

中工作

以下是一些可以帮助您解决此问题的备选方案:

  1. 获取填充对象 class 的所有选择器的集合:
    • anObject class selectors
  2. 获取填充对象的 class 及其所有超classes 的所有选择器的集合:
    • anObject class allSelectors
  3. 询问 class 是否实现了给定的消息(对于它的实例):
    • anObject class canUnderstand: #putTheSelectorHere
  4. 询问对象是否理解给定的消息:
    • anObject respondsTo: #methodSelectorHere
  5. 使用MessageNotUnderstood机制:
    • (见下面的解释)

在上面的 1 和 2 中,您可以使用返回的集合来检查它们是否包含您感兴趣的某个选择器。功能 3、4 和 5 具有更动态的特性。例如,您可以在 class 中改进 #doesNotUnderstand: 方法,如下所示:

MyClass >> #doesNotUnderstand: aMessage
    (delegate respondsTo: aMessage selector)
        ifTrue: [^delegate
           perform: aMessage selector
           withArguments: aMessage arguments].
    ^super doesNotUnderstand: aMessage

这样,如果您的对象收到一条它不理解的消息,它将首先收到 #doesNotUnderstand: 消息(您无需为此做任何事情),您可以在这里决定(例如, 通过使用 #respondsTo: 消息)是否委托它。如果没有,您可以仅依赖默认行为 (super doesNotUnderstand:),这会发出 MessageNotUnderstood 异常信号。

当然,还有第 6 个选项,由消息的发送方处理 MNU 异常,但我认为这不是您要查找的内容。