Hello all,
I wrote a module that has the single task of exporting all the symbols from one package up to its base package name.
E.g. Foo::Bar::Baz goes to just Baz and you can call Baz::quux().
This all works fine and I'm sure there's a module out there that already can do this but it's only a dozen lines of code or so. Anyway.
I'd like to be able to somehow cache what modules have already been exported so as to eliminate a lot of duplicate exports that happen.
I started with a poor man's memoization using a hash but no values ever get assigned to the hash since it's all executing at compile time (I guess).
I also tried inspecting the symbol table to see if the target package name (Baz) already had some CODE and skip it if so. The problem with that is a situation like this: "Foo::Bar qw(Baz)" and "Omg::Bbq qw(Baz)". Only one gets exported, the other dies when called.
So I call upon the wisdom of you, great monks, how to proceed.
Thanks, bmb
UPDATE: some code to illustrate the problem.
# Package/Exporter.pm package Package::Exporter; use strict; use warnings; use Carp qw[confess]; use Data::Dumper; sub import { my( $class, @exports ) = @_; # turn 'Foo::Bar' into 'Foo/Bar' ( my $class_path = $class ) =~ s{::}{/}g; for my $export( @exports ) { no strict 'refs'; # attempt to require 'Foo/Bar/Baz.pm' eval { require "$class_path/$export.pm"; }; # die if there was an error if( $@ ) { confess __PACKAGE__ . "::import ${class}::import problem w +ith $export - $@"; } # warn __PACKAGE__ . "::import ${class}::$export"; # import, just in case "${class}::$export"->import; # loop through everything in 'Foo::Bar::Baz::' my @all_in_namespace = keys %{"${class}::${export}::"}; # only the methods this time my @methods_in_namespace = grep { *{"${class}::${export}::${_} +"}{CODE} } @all_in_namespace; for my $method( @methods_in_namespace ) { # and assign 'Baz::method' to 'Foo::Bar::Baz::method' # warn sprintf( q["%s::%s" = sub () { "%s::%s::%s"}], $export, $method +, $class, $export, $method ); *{"${export}::${method}"}=\&{"${class}::${export}::${metho +d}"}; } } } 1;
# Foo/Bar.pm package Foo::Bar; use strict; use warnings; use base 'Package::Exporter'; 1;
What I'd like to be able to do is somehow cache the fact that Foo::Bar::Baz was exported to Baz so the next time "use Foo::Bar qw(Baz);" is called, it skips the export.# foo.pl use Foo::Bar qw(Baz); print Baz::quux(), "\n";
In reply to Import singleton? by bennymack
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |