Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

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 the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2016-08-30 11:55 GMT
Find Nodes?
    Voting Booth?
    The best thing I ever won in a lottery was:

    Results (417 votes). Check out past polls.