in reply to Re^2: 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]

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 ;-)

Replies are listed 'Best First'.
Re^4: Which "use" statements in a module do "bubble up" to the callers?
by Nocturnus (Scribe) on Sep 01, 2017 at 07:35 UTC

    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).

        Wow, that is tricky. Thank you very much!

        I would not have come to the idea that a pragma's subpragma might be scoped in another way than the pragma itself or its other subpragmas. That's the reason why I haven't found it in the documentation. But even if I had found it: IMHO, "... without mentioning lexical scope." for most people (including myself) implies "With this subpragma, nothing is different regarding the lexical scope from what has been said earlier in that text". This is very worrying and probably should be improved (to make myself clear: The Perl documentation is one of the best documentations I have ever seen, but even in the best documentation, there is always room for improvement).

        Finally, thinking about your last statement in your last comment took me quite a while, and I did some tests. If choroba really tried to say what you suspect, I think he is wrong:

        If I have a lexically scoped pragma at the top my main script, and if I then use another module, the pragma will not be in effect during initialization (i.e. during loading and compiling at compile time) of that other module. I can give a code example if I didn't manage to express clearly enough what I wanted to say.

        Thank you very much,

        Nocturnus