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)
在 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)