in reply to Which "use" statements in a module do "bubble up" to the callers? [SOLVED]

obviously, using the constant TESTCONST in script.pl works as expected

Actually, that's not so obvious from what you've written so far. use Test::Test1; on its own should not cause TESTCONST to be exported from Test::Test1 into the current package unless there is additional code you haven't told us about, such as if you're using Exporter or your script.pl begins with package Test::Test1;. (Update 2: Ok, as per your reply, you don't have a package Test::Test1; at the top of Test1.pm, that explains it too. I wrote this post with the assumption that your Test1.pm begins with package Test::Test1;.)

Is there an overview about which of the various "use ..." statements

Unfortunately, no. There are some rough rules of thumb, such as modules whose names are lowercase are "pragmas" and their effect is often (but not always!) lexically scoped (warnings and strict being the two most common), and regular modules will usually at most export a few functions into your package (although there are lots of exceptions to this rule of thumb). So the short answer is you'll have to look at each module's documentation to see what useing it will do. The long answer is:

Once you understand what's going on under the hood, the mechanisms that Perl uses for modules and pragmas are actually relatively transparent in that there isn't a ton of magic involved, and one can see all the moving parts. When you use a module that you write yourself, here's a rough overview of the mechanisms involved:

  1. When you write use Test::Test1;, then what Perl actually does is BEGIN { require Test::Test1; Test::Test1->import(); } (documented in use), and what require does is explained in detail in its docs, but simplifying a bit, it will search for a file named Test/Test1.pm in the directories listed in @INC and parse and run that file if it hasn't previously done so. Usually, this file will contain a package Test::Test1;, although there is no hard requirement for this. Then, Test::Test1->import() means to call the sub import in the package Test::Test1, passing the string "Test::Test1" as the first parameter (a "class method"), and if there are any parameters in the use statement after the module name and version, pass those as the remaining arguments to import. So you see the basic mechanism here is finding a file, loading it, and calling a sub in that file, which is then free to do whatever it wants, and this is where the "magic" of ex/importing happens.
  2. While you can write a sub import yourself*, that's uncommon because there are several standard implementations, a very common one being the one provided by Exporter. So if in your package Test::Test1; you have written our @ISA = qw/Exporter/;, use base 'Exporter';, or use Exporter 'import';, then your package will be getting Exporter's sub import. What Exporter's import will do is, again very simplified, take the subs and variables you have listed in the package variable @Test::Test1::EXPORT (among others), and install those in the package that called the sub import, i.e. in the package that called the use.
  3. Now as for your question, the effect of use warnings; is limited to the enclosing lexical scope, which in this case is the file, which is why it only affects your Test1.pm. The effect of use constant TESTCONST => 1; is to set up a sub TESTCONST () { 1 }, which means that just like any other sub this definition should be limited to the current package (it is Test::Test1::TESTCONST()), unless you've set up an export/import mechanism like the one I described above to copy it out of that package and into whatever package script.pl uses (main by default).

So you can have modules that export functions in the way I described above, you can have modules that export nothing (usually OO modules), or your own custom "pragmatic" modules that, like warnings, only have an effect in the current lexical scope (documented in perlpragma), or even mixes of these kinds of modules. A close reading of perlmod and the other documentation referenced therein should explain most of this in more detail. Because Perl is very flexible in what it allows module authors to do, it isn't easy to give some general rules as to how modules act, beyond some guidelines and best practices about how modules should be written, and based on that some rules of thumb of what to expect. So you'll have to look at the documentation of each of the modules to see what effects useing them will have. Luckily, most modules have good documentation and the "Synopsis" and further descriptions at the top will usually tell you right away.

I have dozens of scripts which all should use the same basic settings

The recent thread Code Reuse and the threads linked therein (like use y) should help you there. In particular, I have myself used Syntax::Collector and it's a nice module. The only minor drawback is that it uses Exporter::Tiny instead of Exporter, so you can't export variables, only subs (including constants). And just for completeness, here's the code that does what you want without using an extra module:

package Test::Test1; use warnings; use strict; use constant TESTCONST => 123; use base 'Exporter'; our @EXPORT = qw/TESTCONST/; sub import { warnings->import; strict->import; __PACKAGE__->export_to_level(1, @_); return; }

Then, in code that does use Test::Test1;, warnings and strict are enabled and sub TESTCONST is exported as well.

* Update: The basis of what most sub import implementations do is described in the section "Symbol Tables" in perlmod - basically you take the entry for the sub whatever in the current package, &Current::Package::whatever, and copy it to the symbol table of the target module (e.g. main), so that both &main::whatever and &Current::Package::whatever refer to the same piece of code. For completeness, here is an extremely minimalistic implementation of sub import, but this is the basis of what Exporter and related modules do:

our @EXPORT = qw/ ... /; sub import { my $callerpackage = caller; for my $export (@EXPORT) { no strict 'refs'; *{$callerpackage."::".$export} = \&{$export}; } }

Replies are listed 'Best First'.
Re^2: Which "use" statements in a module do "bubble up" to the callers? (updated)
by Nocturnus (Scribe) on Aug 31, 2017 at 16:56 UTC

    Thank you very much for that fantastic explanation!

    You are right, it's all there. I don't know what my problem was; I have read the documentation for "use warnings;" and "use strict;" multiple times before asking, and both quite at the beginning state they are lexically scoped. The documentation for "use warnings;" even states the reason: To prevent "leaking" to callers and other packages ... no idea what has been wrong with me. Probably I have got wrong the term "lexically scoped".

    My next problems were "use utf8;" and "use feature unicode_strings", but I now know that "use utf8;" and "use feature ..." are lexically scoped as well.

    In my module, there are also some commands to set the binmode for STDIN, STDOUT and STDERR. Since I now have understood that there will run a do(module_file_name) when the module is loaded, I can be sure that those commands will be run whenever that module is used - one more understanding problem solved.

    The only thing which I am still wondering about is that the constants are indeed in my script.pl, without having them exported from the module. But I think this is due to the fact that I have no "package ..." statement in that module (yet). Yes, I know, bad style, but still just testing at the moment ...

    And finally, I have decided that I (for the moment) just copy all common "use ..." statements from my module into every script. It is ugly, but it is not too much work. It is very good to know how I could solve this in a clean way, though. I'll do that later.

    Again, thank you very much!

    Nocturnus

      there are also some commands to set the binmode for STDIN, STDOUT and STDERR

      BTW, you can use the open pragma with its :std option for this as well.

      The only thing which I am still wondering about is that the constants are indeed in my script.pl, without having them exported from the module. But I think this is due to the fact that I have no "package ..." statement in that module (yet). Yes, I know, bad style, but still just testing at the moment ...

      Correct on both that it's due to the missing package (that means everything is happening in the default package main) and that it's bad style ;-)

        Although the actual problem has been solved for me, one additional quick question:

        You have mentioned "use open ..." as an alternative to "binmode(...)". But as far as I have understood the documentation, "use open ..." is lexically scoped as well, while "binmode(...)", when being at the beginning of a module which is used by a script, will set the file encoding throughout the whole script.

        So in my case it would not be wise to switch from "binmode(...)" to "use open ...". Did I get this right?

        Best regards,

        Nocturnus