Cees Hek wrote:
> Since the list has been quiet for the last little while, I thought I
> would stir things up a bit.  There was a thread about Class::Trait
> recently on perlmonks that caught my attention:
> 
> http://perlmonks.org/?node_id=509958
> 
> I had looked at Traits before, but never found the time to look into
> them carefully.  The reason I think they are interesting, is that
> Traits aim to solve a lot of the problems with both Multiple
> Inheritance and Mixins.  And since the plugin system in
> CGI::Application is based around a mixin architecture, I think it is
> worth a look.
> 
> In CGI::Application, we don't really have a plugin interface.  We have
> conventions and best practices that tell developers to just use
> Exporter to export methods into the caller class (ie a very simple
> mixin strategy).
> 
> But mixins have some problems and dangers associated with them.  The
> biggest one being method name colisions.  What happens if a plugin
> tries to export a method that already exists in the caller class?  It
> probably clobers it in most instances, depending on how the plugin
> author implemented their code.

How does Class::Trait handle 2 plugins trying to export the same method?

> Traits are not really much more than mixins with a lot of extra checks
> and balances for namespace collisions, and ways to overcome those
> problems when they arise.  First of all, a Trait will never overwrite
> an existing method in the caller.  What it will do is allow you to
> alias the trait method with a new name, so that you can still use the
> method provided by the trait without it conflicting with your existing
> code.

What if you want your plugin to override an existing method? For
instance, CAP::AnyTemplate overrides load_tmpl(), CAP::TT overrides,
load_tmpl(), CAP::Apache overrides query(), etc.

Would we then have to have a mix of Class::Trait and Exporter?

> For example lets take the LogDispatch plugin.  It exports a 'log'
> method into the caller namespace.  Lets say you already have a 'log'
> method in there that you do not want to get rid of.  When you load the
> LogDispatch Trait, you can tell it that you want the 'log' method, but
> you want to call it 'get_logger' instead.  Class::Trait will
> automatically export a 'get_logger' method that is aliased to the
> original 'log' method in the Trait.
> 
> 
> Another nice benefit of Traits is that you can specify method
> requirements in a Trait.  So if I implemented the Session plugin using
> traits, and I put in a requirement that the Session trait requires a
> 'dbh' method to be available, then the Class:Trait module would make
> sure that a 'dbh' is available and provide an error if it can not find
> a dbh method (either in the caller class, or in another Trait that is
> also being loaded).

This is nice. But is there a way to do this now? Can't you write your
own export() method to check for the availability of a method. This may
get kinda tricky if the method is added later, or not completely visible
to export(). But this would still be done at compile time.

> Class::Trait will add a slight bit of extra processing to the module
> at startup, since it is doing more work than a straight Exporter style
> mixin, but all of this work is done at compile time.  All of the
> exported methods are still flattened into the caller's namespace, so
> there is absolutely no extra runtime penalty.
> 
> Loading plugins will also look slightly different, since they are
> loaded through the Class::Trait module instead of being 'use'd
> directly:
> 
> use Class::Trait qw(CGI::Application::Plugin::Session);
> 
> We could create a simple wrapper that simplifies that to something like this:
> 
> use CGI::Application::Plugin qw(Session);
> 
> - or with some extra options -
> 
> use CGI::Application::Plugin
>         'LogDispatch' => {
>             alias => { log => 'get_logger' },
>         },
>         'Session'
> );

Whether or not we use traits, I think having a more uniform way to 'use'
plugins is a good idea.

> I think it might be useful at some point in the future to look at
> using Traits instead of straight exporter style mixins to implement
> the plugin system we use today.  It would add extra safeguards and
> checks into the plugin system that would make it more robust, and it
> adds a clean conflict resolution mechanism in case of method name
> conflicts.

All of these things sound good, I just want to make sure that plugins
can still do tricky stuff if they want to.

-- 
Michael Peters
Developer
Plus Three, LP


---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/[email protected]/
              http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to