in reply to Re^2: Logic for importing and strict vars?
in thread Logic for importing and strict vars?

While experimenting with this code I stepped away from using $a, main and one-liners and I can report to you that the results are exactly the same:

package Foo ; use strict ; our $t = 2 ; { BEGIN { # package Bar ; # added *Foo::x = \$Foo::t; } ++$x ; # ++$Foo::x; # no errors print $x ; # print $Foo::x; # no errors }

Small note regards the Deparse results: With 'package Bar' disabled it looks like *Foo::x = \$Foo::t; becomes: *x = \$t; and with 'package Bar' enabled it becomes: *Foo::x = \$Foo::t;. Inside the BEGIN statement I think it is likely that the first form is not a valid trigger to 'declare' $x and the latter form is valid, but the reason could also be what tye said regards: "when the variable slot of a glob gets assigned to by code compiled into another package". But I am still confused though 'what' declared means. Is it turned into a lexical scoped package variable, or is it similar to 'use vars'?. This line in 'use' documentation is not clear to me:"...which are effective through the end of the file..." in the text: "Some of these pseudo-modules import semantics into the current block scope (like strict or integer , unlike ordinary modules, which import symbols into the current package (which are effective through the end of the file)".

In case you do wish to use this as a one-liner (Windows):

perl -MO=Deparse -wMstrict -e "package Foo ; our $t = 2 ; { BEGIN { package Bar { *Foo::x=\$Foo::t } } ; ++$x ; print $x }"

Replies are listed 'Best First'.
Re^4: Logic for importing and strict vars?
by haukex (Archbishop) on Feb 28, 2019 at 22:24 UTC
    think it is likely that the first form is not a valid trigger to 'declare' $x and the latter form is valid

    Note that what B::Deparse is doing is taking the compiled optree and turning that back into Perl code. It's not perfect, there are sometimes ambiguities about which Perl code produced which op, so it's not always a reliable 1:1 representation of the optree or the original code. It seems to me that this might be one of those cases where it might not be the best tool.

    But I am still confused though 'what' declared means. Is it turned into a lexical scoped package variable, or is it similar to 'use vars'?

    It's too late here for me to go reference hunting in the docs, but as far as I remember right now package variables aren't really declared* - they just have symbol table entries, and what vars does it set up the symbol table entry during compile time (and from another package, as we've learned that's important), such that strict vars considers it "declared". In other words, when compiling package X { *::x=\$a }; $x++;, the assignment to the glob *::x hasn't happened yet by the time $x++; is compiled, so it's an error, but in package X { BEGIN { *::x=\$a } }; $x++;, the assignment to the glob *::x has happened by the time the compiler sees $x++;, and that's considered ok. And yes, there isn't really a formal declaration like with my.

    * I'm not counting our because it "makes a lexical alias to a package variable of the same name".

    This line in 'use' documentation is not clear to me:"...which are effective through the end of the file..."

    AFAICT the "which are effective through the end of the file" refers only to the immediately preceding "the current package" - the effect of a use vars applies to that package, regardless of whether that package spans multiple files.