--- Michael Peters <[EMAIL PROTECTED]> wrote: > Cees Hek wrote: > > > > What is the difference between the plugin choosing > a default namespace > > (and importing a method to access that namespace > into the caller), and > > importing one or two methods directly into the > caller?
The difference is that the user of the plugin controls the naming of the access method and can avoid collisions. > > I appreciate the effort and thought you have put > into this, but I > > honestly think you guys are complicating a very > simple process. Now I [snip] > That was actually one of my fears; that we were > making this too > complicated. I agree that simplicity is the key. > I think that maybe we got excited and started talking too much about implementation details, but the proposed structure is very simple. > > What I am looking for in a plugin is commonly > refered to as a Decorator > > Pattern, where you take an existing class or > object, and decorate it > > with more functionality (that is probably an > oversimplification, but it > > should serve the purpose). > > > > I want my Base class to have more functionality, > without having to cut > > and paste a bunch of code all over the place. > when I use the > > C::A::Session plugin I know that anywhere in my > app I can call > > $self->session and I get my session object. > > Agreed. Also agreed. The access method ultimately gets bolted onto a C::A (or child thereof) object and will be accessible throughout the app. > > If we start importing different plugins into > different namespaces, we > > just complicate the system, and make it more > difficult to use (and to > > share code between developers). > > Say for example I write a plugin called C::A::Auth > which is an > > authentication plugin. This module depends on > C::A::Session. So the > > Auth module will need to know how to access the > Session object. Valid point. Didn't think of plugins using plugins either. I have to think there are ways of allowing this without "crowding" the C::A namespace. The > > Auth module should be able to 'use C::A::Session' > and then call > > $self->session to access the session object (which > will always give it > > the same session instance that the rest of the app > uses). It could also > > call $self->query to get the login and password > from a form if need be. > > This has to do with enforcing a singleton pattern. Its not mutually exclusive to separate namespaces. > > If we start playing with namespaces, this > situation becomes much more > > complicated. The Auth module will not be able to > load the Session > > module by itself, because it may already be loaded > into an unknown > > namespace in another location in the App. OK. A convention for allowing other plugins to discover the namespace of a plugin they seek to use is clearly required. Respectfully, I still firmly believe that the solution must lie in separate namespaces, however. If it loads it into its own > > custom namespace, then any session objects that > are created will not be > > shared with the rest of the app, and we get 2 > sessions objects for a > > single request. So we have to leave it up to the > developer to pass the > > namespace info about the Session to the Auth > module when they use it. This seems to me a area that could be automated by the C::A::Plugin class; by convention or otherwise. To > > me that is unnecesary complexity. > > That's a very valid example. I hadn't thought of > plugins using > other plugins, but it makes perfect sense. We want > to be able to > use plugin2 without telling it a namespace for > plugin1. Yes. Plugins must be discoverable by a common convention, and singleton patterns may need to be available for some plugins - such as config or session. > > Lets look at namespaces from a different angle. > Say in your application > > you want to debug some code by printing out the > contents of some > > variables. A common thing to do is load > Data::Dumper, and you have > > access to the 'Dumper' function to dump your data > structures into human > > readable form. By default the 'Dumper' function > is imported into the > > callers namespace when the Data::Dumper module is > 'use'd. Is this > > inherently bad? Is this a dangerous thing to do? > I don't think it is. I don't like it. Its convenient, but its sloppy. > > This is how perl works, and it is how developers > expect perl to work. True. There is a lot of criticism of some "bad" practices that Perl allows / encourages, however. Its good that Perl allows them for quick hacks, but its often not good for well designed programs. > > I don't think the plugin system is that > different. The main difference > > is that we are talking about methods instead of > functions, but I don't > > think it is a very big leap to get there. > > I do think there is a big difference here between > subs and > methods...The object stored. Most plugins will want > to have some > sort of an object cache so that any objects used in > the back > ground (TT, or CGI::Session or Config::Simple) don't > get > recreated on every method invocation. Yes. > The main reason I thought we needed to solve the > namespace issue > was so that we don't clobber stuff that's being > stored inside of > C::A (in the application object's internal hash) > since this is > where each of the currently available plugins puts > stuff. Also yes. :) > Maybe it could be as simple as a naming convention > that is > respected by C::A and every other plugin. If we > reserve and > element of that internal hash (say > $self->{_Plugins}) and each > plugin uses an element of that has (say > $self->{_Plugins}->{'Config::Simple'} for my > C::A::P::Config::Simple plugin) then no one would > ever overrite > someone else's data. We would also have to ask Jesse > to not use > the '_Plugins' internal hash for C::A. Yes, do this, but as a registry. Create and destroy the registry entry automatically by putting an END block on all plugins. The C::A::Plugin class can do this. BUT, let the user pick the name of the actual object reference as we've been discussing. IOW, don't alias the reference, but register the plugin using a common convention for other plugins to discover. Separately, the plugin may want to be a Singleton - but it would be the Plugin author's responsibility to make sure that was the case - or at least an option. > I don't think we can use > $self->{_Plugins}->{moniker} using > UNIVERSAL::moniker (like we've said before) since > someone could > write a plugin for Config::Simple and CGI::Simple > that should be > able to coexist. > > This would also allow other plugins to not only > access the > methods of other plugins, but the objects directly. > So you Auth > plugin could use $self->session or > $self0->{_Plugins}->{'CGI::Session'} No. I would say that the Auth plugin must use $self->{my_sess_ob_name}->my_sess_ob_method. But, the reference to $self->{my_sess_ob_name} is discoverable at $self->{_Plugins}->{'CGI::Session'}. Again, don't alias the ref at $self->{_Plugins}->{'CGI::Session'} (this would lead to destruction confusion). Just provide a literal and let the plugin user instantiate any ref aliases from that. > I hope that's a little better on the simple side. > > > I won't have much time in the next little while to > work on this stuff, > > so feel free to continue on and refine, and even > implement your ideas. > > It might make things clearer to actually see an > implementation of your > > system to see how it will work in practice. Yep. I think we've setup a good framework. I hope my above suggestions are clear and make sense to others. > Let me know what you (and everyone else on this > list) thinks of > the above ideas and then I'll try and take a crack > at it in the > next few days. Thanks Mike and Cees. Hope we get something everyone likes in the end. Bill --------------------------------------------------------------------- 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]
