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. 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. 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). 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' ); 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. Cheers, Cees --------------------------------------------------------------------- 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]
