Pharo Smalltalk 中的委托

Delegation in Pharo Smalltalk

在 Smalltalk 中进行授权的最佳方式是什么,更具体地说是在 Pharo 中?我知道 doesNotUnderstand 策略,但它不会委托 subclassResponsability 消息。

我正在考虑将未在 class 上显式实现的每条消息发送委托给某个特定对象,就像我可以做的那样,例如,在 Groovy 中使用 @Delegate。是否有一些已知的方法可以做到这一点?

doesNotUndersand: 仅适用于对象不理解的方法(因此名称),因此如果您已经实现了一个方法,它将不会被使用(如 subclassResponsibility.

如果您使用 Pharo 5(应在本周(2016 年 5 月)发布),则可以使用 MetaLinks。这有点矫枉过正,但是你正在做的事情一开始似乎并不正确(你为什么要委托 subclassResponsibility)?

无论哪种情况,MetaLink 都允许将运行时行为附加到您的方法,例如:

您有一些要委托的方法

MyObject>>someMethod
    ^ self subclassResponsiblity

以及您希望委托给的对象...

MyObject>>delegate
    ^ delegate

所以你创建了一个 MetaLink

link := MetaLink new
    metaObject: [ :object :selector :arguments |
        object delegate perform: selector withArguments: argument ];
    selector: #perform:withArguments:;
    arguments: #(object selector arguments);
    control: #instead.

您可以将其安装到您想要的任何方法 AST。

(MyObject>>someMethod ast) link: link.

现在每次调用该方法时,instead(这就是 control: 所做的)执行该方法时,消息的参数(如果有)将被提供给块在 metaObject:.

虽然这应该有效并且是非常强大的机制,但目前存在严重的缺点,目前正在解决:

  • 没有文档
  • 工具支持很少(很难调试)
  • 很多工作(我们正在开发一个框架来简化这个问题,因为您希望轻松地安装它们并在您需要的任何地方卸载它们,但它还没有准备好,因此必须手动完成)
  • 重新编译删除 link(见上文)

总结

总而言之,正如我所展示的那样,这可以通过 MetaLinks 来实现,但目前需要做大量工作,但我们正在解决这些问题。

Peter 所说的是,您可以覆盖 subclassResponsibility,就像您对 doesNotUnderstand 方法所做的那样。 无需覆盖 "self subclassResponsibility".

的每个发件人

比如只委托实现doesNotUnderstand

subclassResponsibility

^ self
    doesNotUnderstand: (Message selector: thisContext sender selector 
                                arguments: thisContext sender arguments)