in reply to Re: Which "use" statements in a module do "bubble up" to the callers? (updated)
in thread Which "use" statements in a module do "bubble up" to the callers? [SOLVED]

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

  • Comment on Re^2: Which "use" statements in a module do "bubble up" to the callers? (updated)

Replies are listed 'Best First'.
Re^3: Which "use" statements in a module do "bubble up" to the callers?
by haukex (Archbishop) on Aug 31, 2017 at 17:06 UTC
    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

        If you use use open at the file scope, it will be lexically scoped to the whole file, too.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
        "use open ..." is lexically scoped as well

        This one is a bit tricky, but the answer turns out to be no, use open qw/:std :utf8/; has a global effect.

        If you read the documentation again, what it says is "Any two-argument open(), readpipe() (aka qx//) and similar operators found within the lexical scope of this pragma will use the declared defaults." But that's not what we're doing here, we're not trying to affect open calls, instead we're trying to change STD(IN|OUT|ERR), and the documentation about that says "The :std subpragma ... converts the standard filehandles (STDIN, STDOUT, STDERR) to comply with encoding selected for input/output handles" without mentioning lexical scope. So as it turns out, the effect of this pragma is actually global, as this quick test shows:

        sub pr { print join(",",@_,PerlIO::get_layers(*STDOUT), "\x{20AC}"),"\n" }
        BEGIN { pr(1); } pr(4);
        do {
        	use open qw/:std :utf8/;
        	BEGIN { pr(2); } pr(5);
        };
        BEGIN { pr(3); } pr(6);
        
        __END__
        
        Wide character in print at o.pl line 5.
        1,unix,perlio,€
        2,unix,perlio,utf8,€
        3,unix,perlio,utf8,€
        4,unix,perlio,utf8,€
        5,unix,perlio,utf8,€
        6,unix,perlio,utf8,€
        

        That warning comes from the very first pr(1); call, because afterwards the utf8 layer is added to STDOUT, and as you can see it stays active for the rest of the script regardless of lexical scope.

        Even if the :std option of the open pragma were to be lexically scoped, what I understand choroba is saying is that if you put the pragma at the top of the main file, it is effectively active for the entire run of the program as well (Update: not quite, see replies).