What is the best way of doing delegation in Smalltalk, more specifically in Pharo? I know of the doesNotUnderstand strategy, but it does not delegates subclassResponsability messages.
I was thinking on something that delegates every message send not explicitly implemented on the class to some specified object, like I can do, for example, with @Delegate in Groovy. Is there some already known way of doing this?
doesNotUndersand:
will only work on methods that the object does not understand (thus the name), so if you already have implemented a method it will not be used (as is the case with subclassResponsibility
.
If you use Pharo 5 (which should be released this week (May 2016)), you could use MetaLinks. It's a bit of an overkill, however what you are doing doesn't seem right to begin with (why would you want to delegate subclassResponsibility)?
In either case, MetaLinks allow to attach runtime behavior to your methods, for example:
You have some method that you want to delegate
MyObject>>someMethod
^ self subclassResponsiblity
And an object to which you wish to delegate to…
MyObject>>delegate
^ delegate
So you create a MetaLink
link := MetaLink new
metaObject: [ :object :selector :arguments |
object delegate perform: selector withArguments: argument ];
selector: #perform:withArguments:;
arguments: #(object selector arguments);
control: #instead.
Which you can install to any method AST you want.
(MyObject>>someMethod ast) link: link.
Now every time the method will be called, instead
(that's what the control:
does) of executing the method, the arguments of the message (if any) will be given to the block in metaObject:
.
Although this should work and is extremely powerful mechanism, right now there are serious disadvantages that currently being addressed:
To summarize, this is possible to do with MetaLinks as I've shown, however at the moment it's quite a lot of work, but we are addressing those issues.