Brett Sanger | 9 Aug 22:02 2005

Plugins Questions

I finally got around to peeking into the internals to see how Plugins
were done, as my ageny looks into a CGIApp overhaul.

All this time I was assuming it was Deep Magic.  And it turns out just
to be an elegant usage of Exporter (which itself does Deep Magic, but
where I don't need to worry about it).  I always thought about Exporter
pushing subs into the main namespace.  I never really thought about it
pushing into package namespaces that then called them as object methods. 

This is really neat!   However, I have a question:

What would be the recommended way of handling internal methods?
Obviously you wouldn't want to populate the app with a bunch of
_private_methods(), as they would start tromping on other Plugins.

I could call my methods directly via the Plugin namespace, but that
kills inheritence.

My next thought would be to push code refs into
$self->{'MyPlugin::Module'}{'subs'}, and calling those:

#simple ugly sample, missing vital chunks that aren't being discussed

package Plugin::Foo;

 <at> EXPORT = qw( &foo);

sub import {
	my $caller = scalar($caller);
	$caller->add_callback('init', \&register_private_methods);
(Continue reading)

Michael Graham | 9 Aug 22:51 2005

Re: Plugins Questions


> What would be the recommended way of handling internal methods?
> Obviously you wouldn't want to populate the app with a bunch of
> _private_methods(), as they would start tromping on other Plugins.
>
> I could call my methods directly via the Plugin namespace, but that
> kills inheritence.

Mark just wrote about this issue in his use.perl.org journal:

   http://use.perl.org/~markjugg/journal/26187

The current practice is that people usually call the private method as a
subroutine, passing $self as the first parameter:

    _internal_method($self,  <at> args);

But you're right - this doesn't allow for plugin inheritance.

It's been bugging me that plugins don't allow inheritence all that well.
However, I think I just figured out how to do it.  It's pretty ugly,
but it works:

    my $_meth = __PACKAGE__ ."::_internal_method";
    $self->$_meth( <at> args);

And for a private method in a superclass, just use:

    $self->SUPER::_internal_method( <at> args);

(Continue reading)

Cees Hek | 9 Aug 23:13 2005
Picon

Re: Plugins Questions

On 8/9/05, Michael Graham <magog <at> the-wire.com> wrote:
> > What would be the recommended way of handling internal methods?
> > Obviously you wouldn't want to populate the app with a bunch of
> > _private_methods(), as they would start tromping on other Plugins.
> >
> > I could call my methods directly via the Plugin namespace, but that
> > kills inheritence.
> 
> Mark just wrote about this issue in his use.perl.org journal:
> 
>    http://use.perl.org/~markjugg/journal/26187

How dare he sully my name in public by airing out my dirty laundry. 
Nasty hacks like that will make people think I am reckless with my OO
design ;)

Just kidding Mark! :)

The reason _internal_method($self,  <at> args) works is really because of
the way OO was added to perl, and is more of a side effect than an
intended feature.  But it works, so I sometimes use it when nothing
else will get the job done.

> However, I think I just figured out how to do it.  It's pretty ugly,
> but it works:
> 
>     my $_meth = __PACKAGE__ ."::_internal_method";
>     $self->$_meth( <at> args);
> 
> And for a private method in a superclass, just use:
(Continue reading)

Michael Graham | 10 Aug 08:42 2005

Re: Plugins Questions


> > However, I think I just figured out how to do it.  It's pretty ugly,
> > but it works:
> >
> >     my $_meth = __PACKAGE__ ."::_internal_method";
> >     $self->$_meth( <at> args);
> >
> > And for a private method in a superclass, just use:
> >
> >     $self->SUPER::_internal_method( <at> args);
>
> But that is still not going to help with inheritance.  You will not be
> able to override the _internal_method, since it will still be called
> directly.  Unless you just want to be able to override public methods?
>  In which case, I guess it would work.

Actually, strangely enough it does seem to work with inheritance, unless
I'm missing something.

To call a private method (with inheritence) you call:

    my $_private_method  = __PACKAGE__ . '::_private_method';
    $self->$_private_method( <at> args);

And to explicitly call a parent class's private method from within a
subclass:

    $self->SUPER::_some_overriden_private_method( <at> args);

Anyway, I'm not sure sure why this syntax works (or whether if it works with
(Continue reading)

Michael Graham | 10 Aug 09:11 2005

Re: Plugins Questions


Oops - typo in one of the comments.  Here's the corrected code:

    use strict;

    $ENV{'CGI_APP_RETURN_ONLY'} = 1;

    my  <at> Method_Trace;

    {

        package CAP::Main;
        use base 'Exporter';
        our  <at> EXPORT = qw(public_method overridden_public_method);

        my $_private_method            = __PACKAGE__ . '::_private_method';
        my $_overridden_private_method = __PACKAGE__ . '::_overridden_private_method';

        sub public_method {
            my $self = shift;
            push  <at> Method_Trace, "CAP::Main - public_method( <at> _)";
        }
        sub overridden_public_method {
            my $self = shift;
            push  <at> Method_Trace, "CAP::Main - overridden_public_method( <at> _)";
        }
        sub _private_method {
            my $self = shift;
            push  <at> Method_Trace, "CAP::Main - _private_method( <at> _)";
        }
(Continue reading)


Gmane