From: James Edward Gray II on
On Mar 21, 2010, at 2:13 AM, Jean-denis Vauguet wrote:

> Another idea I had is the following:
> - any loaded lugin registers as a "callback" for the classes it wants to
> alter (instances of the classes, actually!);
> - through the Plugins module, which is mix-ined within the Base module
> using :extend, have any class nested within the base module to be able
> (forced?), everytime they're initialized, to have their instances
> :extend the plugins which have registered as callback for the class.
>
> Not really sure about it, but...
> Theoretically it would allow for per-instance :extend, thus overriding
> behavior of any instance without the need for aliasing. Same behavior as
> my standalone and Josh codes, but same flexibility as my previous gist
> attempted to achieve.
>
> I'll give it a try when I get the time to, unless I'm told this is BS ;)

If I understand what you are saying correctly, I've used this exact strategy in the past.

I allowed plugins to register themselves on the class object (you can also do that automatically as they are defined with an inherited hook), and then I just extended all instances with the registered plugins as they were created.

It worked great and felt very natural to me when using it.

James Edward Gray II
From: Jean-denis Vauguet on
James Edward Gray II wrote:
> On Mar 21, 2010, at 2:13 AM, Jean-denis Vauguet wrote:
>
>> behavior of any instance without the need for aliasing. Same behavior as
>> my standalone and Josh codes, but same flexibility as my previous gist
>> attempted to achieve.
>>
>> I'll give it a try when I get the time to, unless I'm told this is BS ;)
>
> If I understand what you are saying correctly, I've used this exact
> strategy in the past.
>
> I allowed plugins to register themselves on the class object (you can
> also do that automatically as they are defined with an inherited hook),
> and then I just extended all instances with the registered plugins as
> they were created.
>
> It worked great and felt very natural to me when using it.
>
> James Edward Gray II

Thank you for this feedback. You understood well I guess. This is good
pattern IMO too: you both get rid of dirty aliasing, and enable clean
inheritance with super. I did not have the time to try it out yet, but I
guess it should just work :) If it performs zell, I'll try to make it
more generic (a kind of "Pluginable" gem?).

By the way, would you have any code snippet to illustrate the pattern?
That could come in handy when refactoring my code, for I'm sure you're
definitely more skilled at writing this kind of stuff than I currently
am ;)
--
Posted via http://www.ruby-forum.com/.

From: James Edward Gray II on
On Mar 21, 2010, at 12:44 PM, Jean-denis Vauguet wrote:

> James Edward Gray II wrote:
>> On Mar 21, 2010, at 2:13 AM, Jean-denis Vauguet wrote:
>>
>>> behavior of any instance without the need for aliasing. Same behavior as
>>> my standalone and Josh codes, but same flexibility as my previous gist
>>> attempted to achieve.
>>>
>>> I'll give it a try when I get the time to, unless I'm told this is BS ;)
>>
>> If I understand what you are saying correctly, I've used this exact
>> strategy in the past.
>>
>> I allowed plugins to register themselves on the class object (you can
>> also do that automatically as they are defined with an inherited hook),
>> and then I just extended all instances with the registered plugins as
>> they were created.
>>
>> It worked great and felt very natural to me when using it.
>>
>> James Edward Gray II
>
> Thank you for this feedback. You understood well I guess. This is good
> pattern IMO too: you both get rid of dirty aliasing, and enable clean
> inheritance with super. I did not have the time to try it out yet, but I
> guess it should just work :) If it performs zell, I'll try to make it
> more generic (a kind of "Pluginable" gem?).
>
> By the way, would you have any code snippet to illustrate the pattern?
> That could come in handy when refactoring my code, for I'm sure you're
> definitely more skilled at writing this kind of stuff than I currently
> am ;)

Sure. I added some code like that to Prawn a while back (though I don't think they kept it):

http://github.com/JEG2/prawn/commit/7e25bafe16f508a080a41979bfe25b47f97f0a5e

I hope that helps.

James Edward Gray II


From: Robert Klemme on
On 03/21/2010 06:14 PM, James Edward Gray II wrote:
> On Mar 21, 2010, at 2:13 AM, Jean-denis Vauguet wrote:
>
>> Another idea I had is the following:
>> - any loaded lugin registers as a "callback" for the classes it wants to
>> alter (instances of the classes, actually!);
>> - through the Plugins module, which is mix-ined within the Base module
>> using :extend, have any class nested within the base module to be able
>> (forced?), everytime they're initialized, to have their instances
>> :extend the plugins which have registered as callback for the class.
>>
>> Not really sure about it, but...
>> Theoretically it would allow for per-instance :extend, thus overriding
>> behavior of any instance without the need for aliasing. Same behavior as
>> my standalone and Josh codes, but same flexibility as my previous gist
>> attempted to achieve.
>>
>> I'll give it a try when I get the time to, unless I'm told this is BS ;)
>
> If I understand what you are saying correctly, I've used this exact strategy in the past.
>
> I allowed plugins to register themselves on the class object (you can also do that automatically as they are defined with an inherited hook), and then I just extended all instances with the registered plugins as they were created.
>
> It worked great and felt very natural to me when using it.

James, what's the advantage of this over simply using "include"? If all
instances get to use the plugin module then you can as well include it
in the class.

I see it like this: if all instances of a class should be extended with
plugin behavior, then simply use "include". If only some instances
should, then use "extend".

If plugins also need to be removed at runtime, then a more complicated
solution is necessary (e.g. cooking your own version of "extend" and
using method_missing to delegate to plugged in code - access to instance
variables can then be tricky but you can cope by explicitly passing self
to each method).

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
From: James Edward Gray II on
On Mar 21, 2010, at 1:35 PM, Robert Klemme wrote:

> On 03/21/2010 06:14 PM, James Edward Gray II wrote:
>> On Mar 21, 2010, at 2:13 AM, Jean-denis Vauguet wrote:
>>> Another idea I had is the following:
>>> - any loaded lugin registers as a "callback" for the classes it wants to alter (instances of the classes, actually!);
>>> - through the Plugins module, which is mix-ined within the Base module using :extend, have any class nested within the base module to be able (forced?), everytime they're initialized, to have their instances :extend the plugins which have registered as callback for the class.
>>>
>>> Not really sure about it, but...
>>> Theoretically it would allow for per-instance :extend, thus overriding behavior of any instance without the need for aliasing. Same behavior as my standalone and Josh codes, but same flexibility as my previous gist attempted to achieve.
>>>
>>> I'll give it a try when I get the time to, unless I'm told this is BS ;)
>> If I understand what you are saying correctly, I've used this exact strategy in the past.
>> I allowed plugins to register themselves on the class object (you can also do that automatically as they are defined with an inherited hook), and then I just extended all instances with the registered plugins as they were created.
>> It worked great and felt very natural to me when using it.
>
> James, what's the advantage of this over simply using "include"? If all instances get to use the plugin module then you can as well include it in the class.

There's one massive advantage: the inheritance order. include puts the plugin behind the base class, which is much less useful than extend's behavior of putting it in front of the base class (behind the singleton class, technically). To me, this is the very reason this system is so natural for plugins.

James Edward Gray II