pileofrogs has asked for the wisdom of the Perl Monks concerning the following question:

Ye monks who doth perl encode!

Can I add functions to a package on the fly? For example, could something like this be made to work?

package blort; sub add_method { my $name = shift; ## Do some Magic } ... use blort; blort::add_method('foo'); blort::foo();

I want to know how things like Class::MethodMaker and similer things work. Class::MethodMaker creates the subs at compile time. Is it possible to add subs during run time?

Thanks!
-Pileofrogs

Update: You all rock!! ++ all round! Thanks!

Replies are listed 'Best First'.
Re: Sub on the fly?
by liverpole (Monsignor) on Aug 16, 2006 at 23:07 UTC
    Hi pileofrogs,

    There was this node, by flogic, on that very subject, written just recently.  Have you had a chance to read it yet?


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Sub on the fly?
by chromatic (Archbishop) on Aug 16, 2006 at 23:08 UTC

      Personally I prefer Sub::Install since it does not futz with UNIVERSAL to get the job done.

      -stvn
Re: Sub on the fly?
by ysth (Canon) on Aug 16, 2006 at 23:08 UTC
    Yes, usually with something like *foo = sub { ... };

      However, that would only work if you were within the blork package, so if you wanted to install the method from main:: then this *blork::foo = sub { ... } is more approriate.

      -stvn
        Well, assuming that most of these things will happen dynamically, I'll raise yours by
        { no strict 'refs'; *{ $class . '::' . $name } = sub { ... }; }
        *scnr* Update: As you already did below. *slaps-self*

        Ordinary morality is for ordinary people. -- Aleister Crowley
Re: Sub on the fly?
by stvn (Monsignor) on Aug 17, 2006 at 12:11 UTC
    I want to know how things like Class::MethodMaker and similer things work. Class::MethodMaker creates the subs at compile time. Is it possible to add subs during run time?

    Yes, it is possible to do this at runtime. Basically you need to access the symbol table, which can be done like so (altering your code somewhat).

    sub add_method { my $class = shift; my $name = shift; my $code = shift; no strict 'refs'; # because you should have strict on *{$class . '::' . $name} = $code; }
    Then you can do the following:
    # you must call this as a method, and pass it a CODE ref blort->add_method('foo', sub { print 'bar' }); # now you can do this ... blort::foo();
    Of course there are a number CPAN modules you could use to do this; Sub::Install, Sub::Installer, Class::Accessor, etc.

    -stvn
Re: Sub on the fly?
by kwaping (Priest) on Aug 16, 2006 at 23:27 UTC
    I admit I'm confused... How is what you want different than the functionality AUTOLOAD provides?

    ---
    It's all fine and dandy until someone has to look at the code.

      Well to start with, perl's method dispatch will first look for an inherited method, then go to AUTOLOAD, so if the OP wants to override a method locally they could not do this with AUTOLOAD.

      Also, using AUTOLOAD has a signifigant performance hit, which depending on the complexity of your AUTOLOAD function can easily be something like 4x slower. Not to mention the programmer complexity hit, even the simplest AUTOLOAD function is harder to understand and reason about then a set of simple methods.

      IMO, AUTOLOAD should be a last resort for when you really don't know the names of the methods to be called, and not a tool for reducing typing.

      -stvn