http://www.perlmonks.org?node_id=1085801

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

I have a the following
$filename=getfilenamefromdb(); #gets a name of file require pckg1::pckga::$filename; $result= pckg1::pckg2::$filename::func();

So there is folder 1 as pckg1 inside which we have another folder as pckg2 and then we have .pm files in it whose name is variable so how to access it.

Replies are listed 'Best First'.
Re: filename dynamic
by choroba (Cardinal) on May 12, 2014 at 15:02 UTC
    Just access the symbol table (you have to turn strict refs off):
    $pack = getfilenamefromdb(); # The path or .pm is not part of the pack +age name. require "pckg1/pckg2/$pack.pm"; no strict 'refs'; $result = ${"pckg1::pckg2::$pack\::"}{func}->();
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      The code that you suggested did work perfectly but i did not understand the concept behind it. It would be good if you can tell me what exactly is happening there. Also why did the following did not work

      require pckg1::pckg2::$filename; $result= pckg1::pckg2::$filename::functionname(argument list)

      the above one is giving the error of BAD code after ::

        See the documentation of require. It expects a version or expression as an argument. pckg1::pckg2::$filename is neither one. Namespace can't be built dynamically, you have to access the symbol table to do that. In my code, I use the form of require that isn't a bareword, so it's understood as a filename (that's why I add ".pm" to it). To be able to access the symbol table, you have to turn strict refs off. Then, you can reference the symbol table of a namespace as a hash of the same name plus ::. See Of Symbol Tables and Globs to learn more about symbol tables.
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: filename dynamic
by Anonymous Monk on May 12, 2014 at 16:22 UTC

    I'm not on a system were I can test this so It may need a slight adjustment, but it's the direction that I'd look into using.

    #!/usr/bin/perl use strict; use warnings; use Module::Load; use lib './pckg1/pckg2'; my $filename = getfilenamefromdb(); autoload $filename; my $result = func();
Re: filename dynamic
by hippo (Bishop) on May 12, 2014 at 15:00 UTC

    Is it just a typo? "pckga" is not the same as "pckg2".

Re: filename dynamic
by Anonymous Monk on May 12, 2014 at 15:25 UTC

    And note that the name space the function appears in is the name space given in the package statement (if any) of the .pm file you just loaded, and is not necessarily derived from the file name at all.

    It is true that the normal Perl module loading mechanism needs file Foo/Bar/Baz.pm to provide name space Foo::Bar::Baz, but when you are hand-loading modules like that, anything goes.