assist/control has asked for the wisdom of the Perl Monks concerning the following question:

Hello! First post here.

How is it that package->import imports package into the caller?

I know that I can do the following:

{ package Base; use strict; use warnings; sub import { strict->import; warnings->import; } } { package A; use Base; # Now A has strict and warnings }

… but how does that work? Why is it that Base::import{… strict->import;} is the same as {package A; use strict;}?

Is there an implicit argument to import that’s being passed that tells it to import into the calling package? Or am I misunderstanding a core aspect of use/import behavior?

Replies are listed 'Best First'.
Re: import() into caller
by tobyink (Canon) on Jun 16, 2023 at 05:39 UTC

    The strict and warnings modules are special because they are pragmas. They get imported into whichever level is currently still being compiled.

    Try something like this:

    { package Base; use File::Spec::Functions; sub import { File::Spec::Functions->import; } } { package A; use Base; # Now A doesn't have File::Spec::Functions!!! }

    There's an Import::Into module which does allow you to pass an argument indicating where to import stuff into.

    { package Base; use File::Spec::Functions; use Import::Into; sub import { File::Spec::Functions->import::into( 1 ); # caller level 1 } } { package A; use Base; # Now A has File::Spec::Functions }
Re: import() into caller
by hv (Prior) on Jun 16, 2023 at 12:04 UTC

    If we look at the import function in strict.pm the magic is right there:

    sub import { shift; $^H |= @_ ? &bits : all_bits | all_explicit_bits; }

    So the only actual "payload" is that it sets bits in the global variable $^H. You can get details about that variable in perlvar: $^H and its related hash %^H.

    For more normal modules that simply export functions or variables into a caller's namespace, things are less magical: they interrogate caller to work out which package they should inject into, and then use glob manipulation to do the injection. Taking the start of the code for Exporter::import, for example:

    sub import { my $pkg = shift; # A my $callpkg = caller($ExportLevel); if ($pkg eq "Exporter" and @_ and $_[0] eq "import") { # B *{$callpkg."::import"} = \&import; return; } ...

    .. the use of caller() at A determines the name of the package from which it was called (or "main" if called from the top-level script). At B it injects its own import function into the caller's symbol table by assigning the coderef into the glob (in a manner that requires no strict 'refs').

Re: import() into caller
by NERDVANA (Priest) on Jun 16, 2023 at 16:58 UTC

    The "implicit argument" is the perl function 'caller' which reports the name of the package making the call, among other things. Each individual package that exports things has to deliberately look at 'caller' and decide to write functions into the package one level up. They are also free to do completely different things.

    For this example, as tobyink and hv already pointed out, strict and warnings are special because they just modify the state of the interpreter during the compilation phase (which affects the rest of the compilation of the calling package) rather than actually exporting anything into the caller's package.

Re: import() into caller
by NetWallah (Canon) on Jun 16, 2023 at 04:30 UTC
    From the Exporter Documentation :

    Perl automatically calls the import method when processing a use statement for a module.
    Modules and use are documented in perlfunc and perlmod. Understanding the concept of modules and how the use statement operates is important to understanding the Exporter.

                    "These opinions are my own, though for a small fee they be yours too."

      How does this answer the question?