Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

dynamic symbol Exporter

by bsdz (Friar)
on Nov 15, 2003 at 20:10 UTC ( #307375=perlquestion: print w/replies, xml ) Need Help??
bsdz has asked for the wisdom of the Perl Monks concerning the following question:

Is it possible to export symbols dynamically in a module? For example: -
package A; use strict; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw( build_funcs ); sub build_funcs { foreach ('A', 'B', 'C') { eval " print \"building $_ func\\n\"; sub ${_}_func { print \"$_ func called\\n\"; } "; push @EXPORT, "${_}func"; } } 1;
Using a test function like: -
use strict; use lib '.'; use A; &build_funcs; &A_func;
Any experience with this one?

Replies are listed 'Best First'.
Re: dynamic symbol Exporter
by broquaint (Abbot) on Nov 15, 2003 at 20:28 UTC
    It is indeed possible. Perhaps you want something like this
    sub build_functions { my(@funcs, $pkg) = (@_, scalar caller); for my $f (@funcs) { *{"$pkg\::$f"} = sub { print "I am &$f\n" }; } } build_functions qw/ foo bar baz /; foo(), bar(), baz(); __output__ I am &foo I am &bar I am &baz
    So that just creates the given arguments as dummy functions in the caller's symbol table. See. caller and Of Symbol Tables and Globs for more info.


Re: dynamic symbol Exporter
by simonm (Vicar) on Nov 15, 2003 at 20:28 UTC
    Building subs and pushing them onto @EXPORT or @EXPORT_OK isn't uncommon; I use this same technique in Text::MicroMason.

    However, looking at your code, I think you'll need to move the &build_funcs; call to the end of package A, so that it's executed before the use A completes.

Re: dynamic symbol Exporter
by !1 (Hermit) on Nov 15, 2003 at 20:30 UTC

    Your code is just defining the subroutines within the A namespace. You could use caller to return the namespace in which you want the subroutine exported.

    sub build_funcs { my $package = caller; foreach ('A', 'B', 'C') { eval " print \"building $_ func\\n\"; sub $package\::${_}_func { print \"$_ func called\\n\"; } "; push @EXPORT, "${_}func"; } }

    Of course, you could also use AutoLoader in combination with @ISA in your test script to have an AUTOLOAD that creates the subroutine for you. Also, on a side note, don't get in the habit of calling subroutines as &sub unless you know why you're doing it. Instead use sub(). Read perldoc perlsub for more information about it. I hope this helps you with your problem.

Re: dynamic symbol Exporter
by bsb (Priest) on Dec 22, 2003 at 09:32 UTC
    Depending on the real context, you man also want to write you own import routine. perlmod for details.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://307375]
Approved by broquaint
and a soft breeze sighs...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2017-05-25 21:44 GMT
Find Nodes?
    Voting Booth?