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;
# foo.pl use Foo::Bar qw(Baz); print Baz::quux(), "\n";
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.

In reply to Import singleton? by bennymack

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.