Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Logic for importing and strict vars?

by LanX (Saint)
on Feb 27, 2019 at 13:19 UTC ( [id://1230615]=note: print w/replies, xml ) Need Help??


in reply to Logic for importing and strict vars?

I'm still sleepy and have no documentation...

Here my guess:

Strict doesn't complain about exported vars, they are "declared" implicitly.*

Your last line is not an export but only a simple aliasing, since $x and $a belong to the same package.

*) Most probably the same mechanism use vars is employing.

Update

The fact that $a is a special variable makes it even more complicated...

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Replies are listed 'Best First'.
Re^2: Logic for importing and strict vars?
by Eily (Monsignor) on Feb 27, 2019 at 13:25 UTC

    If that was the case BEGIN { package OfEmpire; *::x=\$::a } would have the same problem, but it's valid. What matters according to tye is the package in which the instruction that overwrites the glob is located.

      Maybe ...

      You are talking about the exact mechanism that defines "exporting" resp. "Importing".

      My statement holds the last line doesn't export.

      Furthermore:

      I can't see tye commenting here.

      And using $a is unfortunate.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re^2: Logic for importing and strict vars?
by haukex (Archbishop) on Feb 28, 2019 at 08:57 UTC
    The fact that $a is a special variable makes it even more complicated...

    I just used it because I wouldn't have to declare it, but it's actually not significant to my example, sorry for the added confusion:

    $ perl -wMstrict -e 'BEGIN { package blah; *::x=\$::y } $x++' Name "main::y" used only once: possible typo at -e line 1. $ perl -wMstrict -e 'BEGIN { *::x=\$::y } $x++' Variable "$x" is not imported at -e line 1. Global symbol "$x" requires explicit package name (did you forget to d +eclare "my $x"?) at -e line 1. Execution of -e aborted due to compilation errors.

      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 }"
        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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1230615]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-20 03:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found