--- 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]

Reply via email to