Perl / perl5

đŸȘ The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 527 forks source link

package NAMESPACE manpage comments #12247

Closed p5pRT closed 11 years ago

p5pRT commented 11 years ago

Migrated from rt.perl.org#113974 (status was 'rejected')

Searchable as RT113974$

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

Created by perl-diddler@tlinx.org

Looking at the 2nd paragraph under package in the perlfunc manpage of 5.14.2\, I see​:

  A package statement affects dynamic variables only\, including   those you've used "local" on\, but not lexical variables\, which   are created with "my"\, "state"\, or "our".

Issues​: 1) package statements affect dynamically ***scoped*** variables -- not dynamic variables (state & my\, usually in subroutines live on a stack. "My" is a dynamic variable with static scoping -- since if you recursively call the same subroutine\, you don't get 1 lexical copy of the 'my' var\, you get 1 for each dynical level (vs. state only get 1 for all levels).

2) package affects 'our'\, despite what it says above. AFAIK\, 'our' only refers to variables that belong to the current package.

Sample prog to demonstrate above​: ---- perl -wE'use strict;   package A;   our $one="A.1";   state $two="A.2";   my $three = "A.3";   local $__PACKAGE__​::four = "A.4";   printf "package=%s\n"\,__PACKAGE__;   package B;   our $one="B.1";   state $two="B.2";   my $three = "B.3";   local $__PACKAGE__​::four = "B.4";   printf "package=%s\n"\,__PACKAGE__;   printf "%s\n"\, join "\, "\, ($one\, $two\, $three\, $__PACKAGE__​::four);   '   "state" variable $two masks earlier declaration in same scope at -e line 10.   "my" variable $three masks earlier declaration in same scope at -e line 11.   package=A   package=B   B.1\, B.2\, B.3\, B.4

my and state complain -- rightfully. but 'our' does not! because it belongs to the package in scope. If what the man page said was true and one was the same type of var as 'my' and 'state'\, you'd get the same type of warning about masking.

3rd) Issue​: You have to use "__PACKAGE__​::four" to not get a warning about the confusion between global var four and four -- even though one is A​::four and the other is B​::four. Without the __PACKAGE__ prefixes (maybe the one in 'B' is enough in this case)\, you get an error​:  
  Global symbol "$four" requires explicit package name at -e line 6.   Execution of -e aborted due to compilation errors.

So why the requirement to put __PACKAGE__ in -- why not assume that if you are in package B\, you mean B​::four unless you override with a different prefix? Or\, in other words -- the behavior that "our $one" shows (even though the documentation claims it should be acting more like "state or my"....

Questions -- what is correct? should 'our' complain like state+my? or is the documentation wrong? (I.e. 'our' means it belongs to the package!)... Shouldn't local be defaulting to that as well rather than requiring an explicity prefix?

And please --- that needs to say dynamically scoped variables\, NOT "dynamic variables"....

linda

Perl Info ``` Flags: category=docs severity=medium This perlbug was built using Perl 5.14.2 - Wed Feb 8 15:59:25 UTC 2012 It is being executed now by Perl 5.14.2 - Wed Feb 8 15:55:36 UTC 2012. Site configuration information for perl 5.14.2: Configured by abuild at Wed Feb 8 15:55:36 UTC 2012. Summary of my perl5 (revision 5 version 14 subversion 2) configuration: Platform: osname=linux, osvers=3.1.0-1.2-default, archname=x86_64-linux-thread-multi uname='linux build09 3.1.0-1.2-default #1 smp thu nov 3 14:45:45 utc 2011 (187dde0) x86_64 x86_64 x86_64 gnulinux ' config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm -Dd_dbm_open -Duseshrplib=true -Doptimize=-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -Wall -pipe -Accflags=-DPERL_USE_SAFE_PUTENV -Dotherlibdirs=/usr/lib/perl5/site_perl' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -fno-strict-aliasing -pipe -fstack-protector -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -Wall -pipe', cppflags='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -fno-strict-aliasing -pipe -fstack-protector' ccversion='', gccversion='4.6.2', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib64 -fstack-protector' libpth=/lib64 /usr/lib64 /usr/local/lib64 libs=-lm -ldl -lcrypt -lpthread perllibs=-lm -ldl -lcrypt -lpthread libc=/lib64/libc-2.14.1.so, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.14.1' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.14.2/x86_64-linux-thread-multi/CORE' cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib64 -fstack-protector' Locally applied patches: @INC for perl 5.14.2: /usr/lib/perl5/site_perl/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.14.2 /usr/lib/perl5/vendor_perl/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.14.2 /usr/lib/perl5/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/5.14.2 /usr/lib/perl5/site_perl/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.14.2 /usr/lib/perl5/site_perl . Environment for perl 5.14.2: HOME=/home/law LANG=en_US.UTF-8 LANGUAGE (unset) LC_COLLATE=C LC_CTYPE=en_US.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=.:/sbin:/usr/local/sbin:/home/law/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/opt/kde3/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin:/usr/lib/qt3/bin:/usr/sbin:/etc/local/func_lib:/home/law/lib:/home/law/bin/lib PERL5OPT=-CSA PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 11 years ago

From @doy

On Tue\, Jul 03\, 2012 at 06​:37​:35PM -0700\, Linda Walsh wrote​:

Looking at the 2nd paragraph under package in the perlfunc manpage of 5.14.2\, I see​:

A package statement affects dynamic variables only\, including
those you've used "local" on\, but not lexical variables\, which
are created with "my"\, "state"\, or "our"\. 

Issues​: 1) package statements affect dynamically ***scoped*** variables -- not dynamic variables (state & my\, usually in subroutines live on a stack. "My" is a dynamic variable with static scoping -- since if you recursively call the same subroutine\, you don't get 1 lexical copy of the 'my' var\, you get 1 for each dynical level (vs. state only get 1 for all levels).

Yeah\, I'm not sure what "dynamic variables" even means here. I don't know what a better term to use is though. Thoughts?

2) package affects 'our'\, despite what it says above. AFAIK\, 'our' only refers to variables that belong to the current package.

No\, it doesn't. Consider​:

  package A;   our $foo = 1;   package B;   say $foo; # prints "1"\, because $foo still refers to $A​::foo

This is what the documentation is referring to. The scope of an 'our' variable is identical to the scope of a 'my' or 'state' variable.

3rd) Issue​: You have to use "__PACKAGE__​::four" to not get a warning about the confusion between global var four and four -- even though one is A​::four and the other is B​::four. Without the __PACKAGE__ prefixes (maybe the one in 'B' is enough in this case)\, you get an error​:

Global symbol "$four" requires explicit package name at \-e line 6\.

Execution of -e aborted due to compilation errors.

So why the requirement to put __PACKAGE__ in -- why not assume that if you are in package B\, you mean B​::four unless you override with a different prefix? Or\, in other words -- the behavior that "our $one" shows (even though the documentation claims it should be acting more like "state or my"....

$__PACKAGE__​::four doesn't do what you seem to think it does - this refers to the variable named '$four' in the package named literally '__PACKAGE__'\, not the current package. 'local' requires explicit scoping under 'use strict' because local isn't actually a variable declaration. It just modifies a variable that already exists. 'strict' requires that all variables that aren't explicitly scoped are declared before use\, and 'local' is a use\, not a declaration.

I think that the use of "dynamic variables" is the only thing here that actually could use improvement.

-doy

p5pRT commented 11 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

Jesse Luehrs via RT wrote​:

On Tue\, Jul 03\, 2012 at 06​:37​:35PM -0700\, Linda Walsh wrote​:

Looking at the 2nd paragraph under package in the perlfunc manpage of 5.14.2\, I see​:

A package statement affects dynamic variables only\, including
those you've used "local" on\, but not lexical variables\, which
are created with "my"\, "state"\, or "our"\. 

Issues​: 1) package statements affect dynamically ***scoped*** variables -- not dynamic variables (state & my\, usually in subroutines live on a stack. "My" is a dynamic variable with static scoping -- since if you recursively call the same subroutine\, you don't get 1 lexical copy of the 'my' var\, you get 1 for each dynical level (vs. state only get 1 for all levels).

Yeah\, I'm not sure what "dynamic variables" even means here. I don't know what a better term to use is though. Thoughts?

---I used the word "scoped" (that was added in my issues text).

2) package affects 'our'\, despite what it says above. AFAIK\, 'our' only refers to variables that belong to the current package.

No\, it doesn't. Consider​:

package A; our $foo = 1; package B; say $foo; # prints "1"\, because $foo still refers to $A​::foo

You didn't declare $foo in B... if you do\, then it overrides -- YES -- just as 'my' and 'state'\, do\, BUT without the warning!.... Shouldn't it warn about 'our' overriding a previous declaration in the same scope?

This is what the documentation is referring to. The scope of an 'our' variable is identical to the scope of a 'my' or 'state' variable.

Warning? Why no

3rd) Issue​: You have to use "__PACKAGE__​::four" to not get a warning about the confusion between global var four and four -- even though one is A​::four and the other is B​::four. Without the __PACKAGE__ prefixes (maybe the one in 'B' is enough in this case)\, you get an error​:

Global symbol "$four" requires explicit package name at \-e line 6\.

Execution of -e aborted due to compilation errors.

So why the requirement to put __PACKAGE__ in -- why not assume that if you are in package B\, you mean B​::four unless you override with a different prefix? Or\, in other words -- the behavior that "our $one" shows (even though the documentation claims it should be acting more like "state or my"....

$__PACKAGE__​::four doesn't do what you seem to think it does - this refers to the variable named '$four' in the package named literally '__PACKAGE__'\, not the current package. 'local' requires explicit scoping under 'use strict' because local isn't actually a variable declaration. It just modifies a variable that already exists. 'strict' requires that all variables that aren't explicitly scoped are declared before use\, and 'local' is a use\, not a declaration.


Um\, where am I supposed to put the strict?

I have it on the first line​: perl -wE'use strict;

(yes we do!)

(pathetic humor)

I think that the use of "dynamic variables" is the only thing here that actually could use improvement.

um.... where am I not using strict -- ok\, here's a fixed version -- and just to show that A​::four is created when I ref package\, I print out the value of A​::four in B\, and it is set. #!/usr/bin/perl -w use 5.14.2; select STDOUT; $|=1;

package A;

our $one="A.1"; state $two="A.2"; my $three = "A.3";

no strict "refs"; local ${__PACKAGE__."​::four"} = "A.4"; use strict;

printf "package=%s\n"\,__PACKAGE__;

package B;

our $one="B.1"; state $two="B.2"; my $three = "B.3";

no strict "refs"; local ${__PACKAGE__."​::four"} = "B.4"; use strict;

printf "package=%s\n"\,__PACKAGE__;

no strict "refs"; printf "%s\n"\, join "\, "\,   ($one\, $two\, $three\, ${__PACKAGE__."​::four"}\, $A​::four);

test.pl "state" variable $two masks earlier declaration in same scope at ./test.pl line 20. "my" variable $three masks earlier declaration in same scope at ./test.pl line 21. Name "A​::four" used only once​: possible typo at ./test.pl line 31. package=A package=B B.1\, B.2\, B.3\, B.4\, A.4

Note __PACKAGE__ in package A and in package B cause resolution of
variable 'four' to be 'four';

But if I try to add a var "five" in package A or B (only in 1\, without a module name\, it won't work at all​: Global symbol "$five" requires explicit package name at ./test.pl line 6. BEGIN not safe after errors--compilation aborted at ./test.pl line 12. Ishtar​:/tmp>

p5pRT commented 11 years ago

From @doy

On Wed\, Jul 04\, 2012 at 02​:20​:45AM -0700\, Linda W wrote​:

1) package statements affect dynamically ***scoped*** variables -- not dynamic variables (state & my\, usually in subroutines live on a stack. "My" is a dynamic variable with static scoping -- since if you recursively call the same subroutine\, you don't get 1 lexical copy of the 'my' var\, you get 1 for each dynical level (vs. state only get 1 for all levels).

Yeah\, I'm not sure what "dynamic variables" even means here. I don't know what a better term to use is though. Thoughts?

---I used the word "scoped" (that was added in my issues text).

I'm not sure. It doesn't feel right\, but I don't know what would be better.

2) package affects 'our'\, despite what it says above. AFAIK\, 'our' only refers to variables that belong to the current package.

No\, it doesn't. Consider​:

package A; our $foo = 1; package B; say $foo; # prints "1"\, because $foo still refers to $A​::foo

You didn't declare $foo in B... if you do\, then it overrides -- YES -- just as 'my' and 'state'\, do\, BUT without the warning!.... Shouldn't it warn about 'our' overriding a previous declaration in the same scope?

Yeah\, I'm not sure why that case doesn't have a warning. It's possible that it should.

3rd) Issue​: You have to use "__PACKAGE__​::four" to not get a warning about the confusion between global var four and four -- even though one is A​::four and the other is B​::four. Without the __PACKAGE__ prefixes (maybe the one in 'B' is enough in this case)\, you get an error​: Global symbol "$four" requires explicit package name at -e line 6. Execution of -e aborted due to compilation errors.

So why the requirement to put __PACKAGE__ in -- why not assume that if you are in package B\, you mean B​::four unless you override with a different prefix? Or\, in other words -- the behavior that "our $one" shows (even though the documentation claims it should be acting more like "state or my"....

$__PACKAGE__​::four doesn't do what you seem to think it does - this refers to the variable named '$four' in the package named literally '__PACKAGE__'\, not the current package. 'local' requires explicit scoping under 'use strict' because local isn't actually a variable declaration. It just modifies a variable that already exists. 'strict' requires that all variables that aren't explicitly scoped are declared before use\, and 'local' is a use\, not a declaration. um.... where am I not using strict -- ok\, here's a fixed version -- and just to show that A​::four is created when I ref package\, I print out the value of A​::four in B\, and it is set. #!/usr/bin/perl -w use 5.14.2; select STDOUT; $|=1;

package A;

our $one="A.1"; state $two="A.2"; my $three = "A.3";

no strict "refs"; local ${__PACKAGE__."​::four"} = "A.4"; use strict;

printf "package=%s\n"\,__PACKAGE__;

package B;

our $one="B.1"; state $two="B.2"; my $three = "B.3";

no strict "refs"; local ${__PACKAGE__."​::four"} = "B.4"; use strict;

printf "package=%s\n"\,__PACKAGE__;

no strict "refs"; printf "%s\n"\, join "\, "\, ($one\, $two\, $three\, ${__PACKAGE__."​::four"}\, $A​::four);

test.pl "state" variable $two masks earlier declaration in same scope at ./test.pl line 20. "my" variable $three masks earlier declaration in same scope at ./test.pl line 21. Name "A​::four" used only once​: possible typo at ./test.pl line 31. package=A package=B B.1\, B.2\, B.3\, B.4\, A.4

Note __PACKAGE__ in package A and in package B cause resolution of variable 'four' to be 'four';

Yes\, in this example you used ${__PACKAGE__."​::four"}\, which does refer to the correct variable. Previously you had used $__PACKAGE__​::four\, which does not.

But if I try to add a var "five" in package A or B (only in 1\, without a module name\, it won't work at all​: Global symbol "$five" requires explicit package name at ./test.pl line 6. BEGIN not safe after errors--compilation aborted at ./test.pl line 12. Ishtar​:/tmp>

Yes\, this is the entire point of "use strict 'vars'". All variables must be declared before they are used\, unless you explicitly add the package name\, either like $A​::four\, or ${__PACKAGE__."​::four"} (which requires you to disable strict 'refs'\, because that's using a symbolic reference to access the variable). If you want perl to just assume that you mean $B​::four when you use $four in package B\, you'll need to disable strict 'vars' (but that's generally not a good idea).

-doy

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

Jesse Luehrs wrote​:

On Wed\, Jul 04\, 2012 at 02​:20​:45AM -0700\, Linda W wrote​:

1) package statements affect dynamically ***scoped*** variables -- not dynamic variables

Yeah\, I'm not sure what "dynamic variables" even means here. I don't know what a better term to use is though. Thoughts?

---I used the word "scoped" (that was added in my issues text).

I'm not sure. It doesn't feel right\, but I don't know what would be better.


  Well\, I used that because that's the computer science term. In my mind\, the word 'lexical' is more obscure than talking about the 'scope' of something and whether or not it is dynamic. When I hear lex\, I think of lexers doing a 2nd level parse of input in a compiler.

2) package affects 'our'\, despite what it says above. AFAIK\, 'our' only refers to variables that belong to the current package.

No\, it doesn't. Consider​:

package A; our $foo = 1; package B; say $foo; # prints "1"\, because $foo still refers to $A​::foo

You didn't declare $foo in B... if you do\, then it overrides -- YES -- just as 'my' and 'state'\, do\, BUT without the warning!.... Shouldn't it warn about 'our' overriding a previous declaration in the same scope?

Yeah\, I'm not sure why that case doesn't have a warning. It's possible that it should.

Well I find the above a bit surprising. Please note -- I did "use strict" in the first line of my program. The manpage on 'our' (also part of perlfunc) has​:

  our EXPR   our TYPE EXPR   our EXPR : ATTRS   our TYPE EXPR : ATTRS   *"our" associates a simple name with a package variable in the   current package for use within the current scope*. *When "use   strict 'vars'" is in effect\, "our" lets you use declared global   variables without qualifying them with package names\, within   the lexical scope of the "our" declaration.* In this way "our"   differs from /"use vars"\, which is package-scoped. /   Unlike "my" or "state"\, which allocates storage for a variable   and associates a simple name with that storage for use within   the current scope\, "our" associates a simple name with a   package (read​: global) variable in the current package\, for use   within the current lexical scope. In other words\, "our" has   the same scoping rules as "my" or "state"\, but does not   necessarily create a variable.

Ah... I see what I more often want is "use vars"... as it seems to be guaranteed to be package specific. it seems recommending 'our' as a replacement for 'use vars'\, is bad practice and as such vars will carry over to subsequent packages in the same file.

I end up getting the same effect as I've fallen into the habit of enclosing all packages other than main in braces to contain waywardly scoped items like this.

'strict' requires that all variables that aren't explicitly scoped are declared before use\, and 'local' is a use\, not a declaration.

um.... where am I not using strict?? Local works as a declaration​:

perl -e'use warnings;

use strict; local $a=1+1; print $a."\n";' 2 --- no warnings.

Also use strict was in my first line.

-- ok\, here's a fixed version[ of using __PACKAGE__] (many lines deleted in requote)... to show that A​::four is created when I ref __package__\, I print out the value of A​::four in B\, and it is set. ------------ package A; our $one="A.1";state $two="A.2";my $three = "A.3"; local ${__PACKAGE__."​::four"} = "A.4" package B; our $one="B.1";state $two="B.2";my $three = "B.3"; local ${__PACKAGE__."​::four"} = "B.4"; printf "package=%s\n"\,__PACKAGE__; printf "%s\n"\, join "\, "\, ($one\, $two\, $three\, ${__PACKAGE__."​::four"}\, $A​::four);

package=A package=B B.1\, B.2\, B.3\, B.4\, A.4

Note __PACKAGE__ in package A and in package B cause resolution of variable 'four' to be 'four';

if I try to add a var "five" in package A or B (only in 1\, without a module name\, it won't work at all​: Global symbol "$five" requires explicit package name at ./test.pl line 6. BEGIN not safe after errors--compilation aborted at ./test.pl line 12. Ishtar​:/tmp>

Yes\, this is the entire point of "use strict 'vars'". or 'our'....(or local)... All variables must be declared before they are used\, which I did using 'our'.. our gives them the name of the current package for the remainder of the current scope -- more than a bit confusing\, since if you don't isolate packages with braces in a file\, you have name space bleedover...

I wasn't aware 'our' had such risks\, compared to use vars...

Why was it designed that way??

If you want perl to just assume that you mean $B​::four when you use $four in package B\, you'll need to disable strict 'vars';


no.. just declare it with 'our'... and keep your namespaces separate​:

perl -wE' package Acme;   use warnings;use strict;"   our $counter;   sub inc_cnt {++$counter};   sub pcnt{printf "%s\n"\, $counter//"undef";};   sub newref{   bless {}\,__PACKAGE__;   }

package main;   use warnings;use strict;   my $ref=Acme->newref();   $ref->inc_cnt;   $ref->pcnt;   printf "Acme.counter=%s\n"\, $Acme​::counter;   printf "no-prefix counter=%s\n"\, $counter; ' (output...)

1 Acme.counter=1 no-prefix counter=1


But maybe you are including the use of 'our' in your definition of allowed declarations...?

Having package claim that it doesn't affect 'our' is not really true -- it gives it its' name when declared\, it just define it's scope -- that's only done by the better 'use vars'... which keeps vars in the scope of their packages.

Why was 'our' created to have a random scope compared to the package?

Ugly...

p5pRT commented 11 years ago

From @cpansprout

On Wed Jul 04 19​:41​:54 2012\, LAWalsh wrote​:

perl -e'use warnings;

use strict; local $a=1+1; print $a."\n";' 2 --- no warnings.

Also use strict was in my first line.

The variables $a and $b are exempt\, as documented in perlvar\, because sort uses them.

Why was 'our' created to have a random scope compared to the package?

Ugly...

I don’t know why. Perhaps because ‘use vars’ already provides package scoping?

In any case\, I have actually used ‘our’ to be able to access the same variable in different packages in the same file\, without having to import it into each separate package. I consider that a feature.

--

Father Chrysostomos

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

Father Chrysostomos via RT wrote​:

I don’t know why. Perhaps because ‘use vars’ already provides package scoping?

In any case\, I have actually used ‘our’ to be able to access the same variable in different packages in the same file\, without having to import it into each separate package. I consider that a feature.

Fair enough\, ... ..though sharing a global var between different packages in the same file -- you admit that in public?? ;-)

and just my luck to use "a" and "b"... (me)-(foot)\<-[bang]

BUT... this is a problem​:

{ package A;   use vars qw($aa $bb $cc);   $aa=1;   $bb=2;   $cc=3;   our ($dd\, $ee\, $ff);   $dd=11;   $ee=22;   $ff=33; } { package B;   use vars qw($aa $bb);   $aa=4;   $bb=5;   our ($dd\, $ee);   $dd=44;

} { package A;   print "aa=$aa\n";   print "bb=$bb\n";   print "cc=$cc\n";   print "dd=$dd\n";

} '


'dd' doesn't carry over to future mentions of package A...

and while 'aa/bb' do\,

I have this in from 5.10​: NAME   vars - Perl pragma to predeclare global variable names (obsolete)

SYNOPSIS   use vars qw($frob @​mung %seen);


OBSOLETE?!?

What replaces this functionality? as shown above\, 'our' doesn't work.

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

Father Chrysostomos via RT wrote​:

I don’t know why. Perhaps because ‘use vars’ already provides package scoping?

In any case\, I have actually used ‘our’ to be able to access the same variable in different packages in the same file\, without having to import it into each separate package. I consider that a feature.

Fair enough\, ... ..though sharing a global var between different packages in the same file -- you admit that in public?? ;-)

and just my luck to use "a" and "b"... (me)-(foot)\<-[bang]

BUT... this is a problem​:

{ package A;   use vars qw($aa $bb $cc);   $aa=1;   $bb=2;   $cc=3;   our ($dd\, $ee\, $ff);   $dd=11;   $ee=22;   $ff=33; } { package B;   use vars qw($aa $bb);   $aa=4;   $bb=5;   our ($dd\, $ee);   $dd=44;

} { package A;   print "aa=$aa\n";   print "bb=$bb\n";   print "cc=$cc\n";   print "dd=$dd\n";

} '


'dd' doesn't carry over to future mentions of package A...

and while 'aa/bb' do\,

I have this in from 5.10​: NAME   vars - Perl pragma to predeclare global variable names (obsolete)

SYNOPSIS   use vars qw($frob @​mung %seen);


OBSOLETE?!?

What replaces this functionality? as shown above\, 'our' doesn't work.

p5pRT commented 11 years ago

From @xdg

On Thu\, Jul 5\, 2012 at 11​:36 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

OBSOLETE?!?

What replaces this functionality? as shown above\, 'our' doesn't work.

Nothing replaces it. The intent is that (under strictures) programmers should either use "our" in *every* scope they need a short alias to a package variable\, or they should use the fully qualified name.

That said\, I think that "obsolete" is not a valid term per perlpolicy\, and it should probably be changed in the documentation to "discouraged"\, to make it clear that it's not going away\, but that people should think twice (or three times) before using it for new code.

FWIW\, in your A/B example\, I would probably write it to have package B be a *nested* scope within package A\, rather than having three successive scopes A/B/A. For me\, repeated namespaces in serial scopes are a code smell -- a sign that I haven't sufficiently modularized the code.

Regards\, David

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

David Golden wrote​:

FWIW\, in your A/B example\, I would probably write it to have package B be a *nested* scope within package A\, rather than having three successive scopes A/B/A. For me\, repeated namespaces in serial scopes are a code smell -- a sign that I haven't sufficiently modularized the


  Is nested package scoping documented somewhere?...

  I get regularly flamed for just wanting to put multiple packages in the same file -- I can't imaging the reaction that would occur with I use nested packages...

  Generally I agree though main occurs by *default* at the top... where one usually wants to put one's "main globals" -- or program constants that define behavior for the program (when the program isn't sufficiently advanced to take options\, for example)... but I tend to be old school and prefer defining things B4 I use them -- meaning code for 'main' would go at the bottom.

  That's the only example I can think off off hand where I tend to split scope -- but it does happen frequently and having variables declared one place not be declared the other place ..

  Well\, If I define a package in an object oriented language like C++ -- i.e. things they call PACKAGE variables (which is what "our" variables are called under "our" -- which sounds like it is more than a little misleading!)... then define more of that package someplace else (another file\, another part of same file...whatever)\, I would expect those PACKAGE variables to be available to the PACKAGE!... not constrained to a local definition.

  I don't even like the word "discouraged" -- because too many people\, refer to "our" as package variables -- Which they ARE -- "sorta"\, BUT...they continue on in the current scope even into other packages.

So when you use an 'our' variable\, it's not necessarily a package variable of the current package!...

To quote 'Randal L Schwartz'​:(http​://www.stonehenge.com/merlyn/UnixReview/col46.html)  
  Some of the variables in a Perl program are /package variables/ (also called /symbol-table   variables/). A package variable's full name consists of a package prefix followed by the   specific identifier for the variable. The prefix is separated from the identifier by a double   colon.

==== I.e. a package variable\, according to Randal is a var​: ${__PACKAGENAME__."​::var"};

which is *exactly* what "our" creates\, but it is not really a package var\, UNLESS you scope your packages. Example​: (sidenote​: P is short-hand for something like print/say w/undef check). #!/usr/bin/perl -w use strict; use P; package default; { package A;   use P;   P "package ".__PACKAGE__." is the setter";   our $foobar=22; };   our $wildcard="*";

package B; use P; P "now in package ".__PACKAGE__."."; no strict 'refs';   P "A​::foobar=%s\, wildcard=%s\, and wc=%s\n"\,   $A​::foobar\, $wildcard\, $default​::wildcard;   printf "but not likely will B​::wildcard work​: %s\n"\,   eval("\$"."B​::wildcard")


So in package B\, referencing a package var\, 'A​::foobar'\, references 'A' package variable. and to reference wildcard\, can use it with or without the 'default' prefix.

So somehow it just seem WRONG to be referring to 'our' vars as package variables when really it is "use vars" that are the true packgage variables that are (obsolete?) or "discouraged"....

But when people want package variables -- what are they going to be told to use?

our's? when it's not? or "use vars" when it is?

p5pRT commented 11 years ago

From @cpansprout

On Thu Jul 05 15​:44​:55 2012\, LAWalsh wrote​:

I don't even like the word "discouraged" \-\- because too many people\, 

refer to "our" as package variables -- Which they ARE -- "sorta"\, BUT...they continue on in the current scope even into other packages.

So when you use an 'our' variable\, it's not necessarily a package variable of the current package!...

‘our’ could certainly be documented better. Somewhere we need to state it nice and clearly like this​:

C\ makes a lexical alias to a package variable.

--

Father Chrysostomos

p5pRT commented 11 years ago

From @xdg

On Thu\, Jul 5\, 2012 at 6​:44 PM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

Is nested package scoping documented somewhere?\.\.\.

It's just a natural consequence of scoping. A package statement (without a trailing block) doesn't create a scope -- it merely changes the namespace of the remainder of the compilation of that scope.

I get regularly flamed for just wanting to put multiple packages in the

same file -- I can't imaging the reaction that would occur with I use nested packages...

I don't know the situation you're in -- if you have a particular constraint that forces you to keep everything in a single file. I wouldn't flame you for it\, but as I said\, in my *own* code\, having multiple namespaces in one file is a warning to me that I haven't modularized my code enough.

There are exceptions\, usually when I need to monkey patch some other module -- and sometimes I might include a small class as a separate package -- but *very* rarely do I access variables directly across packages.

"our" -- which sounds like it is more than a little misleading!)...

I suspect that it's intended to sound related to "my".

Personally\, I find the opening paragraph of the 'our' documentation to be correct\, but understanding why does require understanding all the jargon.

So when you use an 'our' variable\, it's not necessarily a package variable of the current package!...

Right. The package is associated when you say "our $foo"\, and then $foo remains associated with that package for the rest of the scope (even if the active package subsequently changes).

So somehow it just seem WRONG to be referring to 'our' vars as package variables when really it is "use vars" that are the true packgage variables that are (obsolete?) or "discouraged"....

"our" variable *are* package variables -- but the package is bound to the identifier when the "our" declaration appears. It is not dynamic as the active namespace changes. Maybe that's what needs clarifying.

As far as I know\, nothing built-in is dynamic in that way. Even "use vars" is not dynamic\, the package is bound when 'use vars' appears. It's just file-scoped rather than block-scoped -- making it truly a 'global' for the file\, whereas 'our' creates an alias for the package variable only for a block (which could also be the same as the file\, if it appears top level).

I agree that the documentation as written is confusing for someone not already very familiar with the jargon.

-- David

p5pRT commented 11 years ago

From @xdg

On Thu\, Jul 5\, 2012 at 7​:03 PM\, Father Chrysostomos via RT \perlbug\-followup@&#8203;perl\.org wrote​:

‘our’ could certainly be documented better. Somewhere we need to state it nice and clearly like this​:

C\ makes a lexical alias to a package variable.

Good way to put it.

In commit 66b3001\, I've adapted that and tried to clarify documentation for 'our'.

In commit 4d457ce\, I have removed "obsolete" from the abstract for vars.pm and instead added a phrase in the first paragraph that uses the term 'discouraged' and clarifies that it is discouraged for use within a single scope. I think that better limits *when* vars.pm is discouraged\, as the rest of the documentation explains the scoping of vars.pm and use with Self/AutoLoad\, for which it may indeed be appropriate.

In commit 4dd9551\, I clarified the 'package' documentation to refer to 'lexically-scoped' variables rather than 'lexical' variables\, which might alleviate some confusion (short of documentation-wide fixes to the confusing term 'dynamic').

Ricardo and I apparently also collided on some other commits to clarify vars.pm behavior (which is across even file-scope) and once he integrates his commits\, collectively\, I think these all are sufficient to close this ticket.

-- David

p5pRT commented 11 years ago

From @doy

On Thu\, Jul 05\, 2012 at 08​:18​:47PM -0400\, David Golden wrote​:

On Thu\, Jul 5\, 2012 at 7​:03 PM\, Father Chrysostomos via RT \perlbug\-followup@&#8203;perl\.org wrote​:

‘our’ could certainly be documented better. Somewhere we need to state it nice and clearly like this​:

C\ makes a lexical alias to a package variable.

Good way to put it.

In commit 66b3001\, I've adapted that and tried to clarify documentation for 'our'.

In commit 4d457ce\, I have removed "obsolete" from the abstract for vars.pm and instead added a phrase in the first paragraph that uses the term 'discouraged' and clarifies that it is discouraged for use within a single scope. I think that better limits *when* vars.pm is discouraged\, as the rest of the documentation explains the scoping of vars.pm and use with Self/AutoLoad\, for which it may indeed be appropriate.

In commit 4dd9551\, I clarified the 'package' documentation to refer to 'lexically-scoped' variables rather than 'lexical' variables\, which might alleviate some confusion (short of documentation-wide fixes to the confusing term 'dynamic').

Ricardo and I apparently also collided on some other commits to clarify vars.pm behavior (which is across even file-scope) and once he integrates his commits\, collectively\, I think these all are sufficient to close this ticket.

Not quite - we still need to fix "dynamic variables"\, and decide whether multiple 'our' declarations in the same scope should warn\, like 'my' declarations do.

-doy

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

` David Golden via RT wrote​:

It's just file-scoped rather than block-scoped -- making it truly a 'global' for the file Seems to hold across files as well​:

Ishtar​:bin> more b.pl #!/usr/bin/perl # use utf8; # use feature 'unicode_strings'; use pck2; use P; package alpha; use vars qw($aa $bb); Pe "in file​: ". __FILE__. ' package​: '. __PACKAGE__; Pe "aa=$aa\, bb=$bb\n";


Ishtar​:bin> more lib/pck2.pm #!/usr/bin/perl -w use 5.14.2; #use utf8; #use feature 'unicode_strings'; package alpha; use P; use vars qw($aa $bb); $aa='one'; $bb='two'; Pe "in pkg %s\, aa=%s\, bb=%s"\, __PACKAGE__\, eval '$aa'\, eval '$bb'; package beta; use P; Pe "---------------------\nIn pkg ". __PACKAGE__ ."\n\n"; Pe "aa=%s\, bb=%s"\, eval '$aa'\, eval '$bb'; 1;


Output​: Ishtar​:bin> b.pl in pkg alpha\, aa=one\, bb=two


In pkg beta

aa=undef\, bb=undef in file​: ./b.pl package​: alpha aa=one\, bb=two

I agree that the documentation as written is confusing for someone not already very familiar with the jargon.


I think 'use vars' creates the vars on a trans-file-global basis...which would explain why they would be cautioned against... HOWEVER\, they should be documented as being such...

This still leaves a 'hole'\, for package -specific vars that would come in and out of existence only when within the scope of a package...i.e. "true package variables"...

I don't know how much people want that...but given all the other flavors\, it certainly seems to be the flavor that is missing.

Since 'our' is an **alias**\, to PACKAGE​::var\, for the remainder of the dynamic scope\, it works for me to put brackets around each of my packages\, and another instance of 'ours' at the top --- though having an include facility to include identical blocks wouldn't be a bad idea... as 'use' would push them all down a context (yeah\, you can always push yourself up a context from use\, and define the vars... maybe a cpan-level include would suffice... depends if // the semantics in the use'd file can be "up-leveled"

BTW... FWIW\, when I went to use alpha/beta\, I thought why not add some unicode... Badness happened.

p5pRT commented 11 years ago

From @cpansprout

On Thu Jul 05 17​:23​:06 2012\, doy@​tozt.net wrote​:

Not quite - we still need to fix "dynamic variables"\,

I have often been confused as to why they are called that. Perhaps because they can be swapped out dynamically with local and *foo = ...? ‘Package variables’ would be a better term.

and decide whether multiple 'our' declarations in the same scope should warn\, like 'my' declarations do.

One of my pet peeves​: I can’t use prefix ‘our’ when I use $AUTOLOAD\, because it might warn. I have to put ‘our $AUTOLOAD;’ at the top\, which is sometimes less convenient that putting it next to each use (making refactoring easier).

It should probably only warn if the second ‘our’ is in a different package.

--

Father Chrysostomos

p5pRT commented 11 years ago

From @cpansprout

On Thu Jul 05 17​:19​:47 2012\, xdaveg@​gmail.com wrote​:

On Thu\, Jul 5\, 2012 at 7​:03 PM\, Father Chrysostomos via RT \perlbug\-followup@&#8203;perl\.org wrote​:

‘our’ could certainly be documented better. Somewhere we need to state it nice and clearly like this​:

C\ makes a lexical alias to a package variable.

Good way to put it.

If only it were true. :-) I doesn’t play nicely with package aliasing\, but I plan to fix that soon.

In commit 66b3001\, I've adapted that and tried to clarify documentation for 'our'.

+the lexical scope of the C\ declaration. In this way\, C\ differs from +C\\, which creates file-scoped aliases instead.

I think you meant package-scoped.

--

Father Chrysostomos

p5pRT commented 11 years ago

From @doy

On Thu\, Jul 05\, 2012 at 06​:09​:17PM -0700\, Father Chrysostomos via RT wrote​:

On Thu Jul 05 17​:23​:06 2012\, doy@​tozt.net wrote​:

Not quite - we still need to fix "dynamic variables"\,

I have often been confused as to why they are called that. Perhaps because they can be swapped out dynamically with local and *foo = ...? ‘Package variables’ would be a better term.

But $Foo​::bar is also a package variable\, and it is unaffected by a package declaration. David Golden suggested "unqualified variables"\, which also isn't quite right (because of lexicals)\, but "unqualified package variables" might be good enough.

and decide whether multiple 'our' declarations in the same scope should warn\, like 'my' declarations do.

One of my pet peeves​: I can’t use prefix ‘our’ when I use $AUTOLOAD\, because it might warn. I have to put ‘our $AUTOLOAD;’ at the top\, which is sometimes less convenient that putting it next to each use (making refactoring easier).

It should probably only warn if the second ‘our’ is in a different package.

This is in fact the opposite situation to what happens currently - there is a warning for multiple declarations in the same package\, but not if they are in different packages(​:

-doy

p5pRT commented 11 years ago

From @doy

On Thu\, Jul 05\, 2012 at 06​:11​:48PM -0700\, Father Chrysostomos via RT wrote​:

In commit 66b3001\, I've adapted that and tried to clarify documentation for 'our'.

+the lexical scope of the C\ declaration. In this way\, C\ differs from +C\\, which creates file-scoped aliases instead.

I think you meant package-scoped.

This was clarified in 848bab4.

-doy

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

` Jesse Luehrs via RT wrote​:

On Thu\, Jul 05\, 2012 at 06​:11​:48PM -0700\, Father Chrysostomos via RT wrote​:

In commit 66b3001\, I've adapted that and tried to clarify documentation for 'our'.

+the lexical scope of the C\ declaration. In this way\, C\ differs from +C\\, which creates file-scoped aliases instead.

I think you meant package-scoped.


  Actually\, as near as I can tell\, they are at the Perl-global level -- and exist outside of packages -- and outside of files.

They are accessible to any package that "uses them"\, but don't belong to any package.

They are the true GLOBAL variables\, but only accessible in those packages that "use vars" them.

At least that's how I understand it from my testing...if that's not what other people think\, I'd like to know why given the posted test progs...

This was clarified in 848bab4.

-doy

p5pRT commented 11 years ago

From @rjbs

Actually\, as near as I can tell\, they are at the Perl-global level -- and exist outside of packages -- and outside of files.

They are accessible to any package that "uses them"\, but don't belong to any package.

They are the true GLOBAL variables\, but only accessible in those packages that "use vars" them.

At least that's how I understand it from my testing...if that's not what other people think\, I'd like to know why given the posted test progs...

I wrote a blog post about what use vars vars are\, some time ago. Here​: http​://rjbs.manxome.org/rubric/entry/1862

It's not very complicated. It works like this​:

When you create an alias in your package to a variable in another package\, it's marked "imported" so that you can refer to it easily. This is great when you want to get constant $OK from HTTP​::Whatever and just say $OK. The Exporter does *YourPkg​::OK = \$HTTP​::Whatever​::OK and the little "I was imported!" flag is set on $YourPkg​::OK so that when you say "$OK" in YourPkg\, it's permitted because you specifically asked for that variable from elsewhere.

"use vars" means "mark these variables as imported\, even though they are not."

If you "use vars '$x'" in package Foo\, then anywhere that you switch into package Foo\, $x will mean $Foo​::x (unless it has been shadowed by a lexial name).

In no case does this $x become a superglobal\, available without qualification everywhere. It's always accessible as $Foo​::x\, sometimes as $x\, and that's that.

"our" variables are available by short name in the enclosing lexical scope.

"use vars" variables are available by short name whenever in the importing package.

-- rjbs

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

` Ricardo Signes via RT wrote​:

When you create an alias in your package to a variable in another package\, it's marked "imported" so that you can refer to it easily.


  No probe\, but what alias is created with "use vars qw(aa bb));"??

I.e. to what package? Not the current one -- since (ex.​: Same two files as before\, but in file pkg.pm\, I add a use vars in the 2nd package and then display vars​:

In no case does this $x become a superglobal\, available without qualification everywhere. It's always accessible as $Foo​::x\, sometimes as $x\, and that's that.


Yes you're right\, I misinterpreted two of my lines...

So what I hoped at first\, was that 'use vars'\, then is REALLY the way to get a package variable that is only tied to that package and doesn't wander to other packages based on physical scope unless they specifically prefix it.

To me\, even though 'use vars' is more cumbersome to use\, it's a logical\, name space partitioned variable\, while "our" is a physically partitioned variable that is named from the current name space.

"our" variables are available by short name in the enclosing lexical scope.

How do you get from physical scoping to the word lexical which means "of the grammar or language?...Tried to look up derivation of lexical\, and I don't see the relation to it's original meaning... almost like someone used it not knowing the.

In this case it is a physical scoping vs. a logical scoping.

With state both are physically scoped as well\, though my is also dynamically scoped.

I think those are the differences and terms that need to be emphasized and used.

Please correct this if you think it is wrong​:

Scoping Physical logical Dynamic Type -------- ----------- ----------- my yes no yes state yes no no our yes partial no local no no yes use_vars no   yes no

"use vars" variables are available by short name whenever in the importing package.


but not different packages\, right?

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 1​:48 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

**

` Ricardo Signes via RT wrote​:

When you create an alias in your package to a variable in another package\, it's marked "imported" so that you can refer to it easily.

---- No probe\, but what alias is created with "use vars qw(aa bb));"??

I think you mean C\<\< use vars qw( $aa $bb ); >>

It aliases $aa in the current package to an anonymous scalar created through autovivification in &vars​::import.

Same for $bb.

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 1​:48 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

**

"our" variables are available by short name in the enclosing lexical scope.

How do you get from physical scoping to the word lexical which means "of the grammar or language?...Tried to look up derivation of lexical\, and I don't see the relation to it's original meaning... almost like someone used it not knowing the.

http​://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_and_dynamic_scoping

In this case it is a physical scoping vs. a logical scoping.

huh? There's no such thing

With state both are physically scoped as well\, though my is also dynamically scoped.

No\, state\, my and our are not dynamically scoped. They are lexically scoped​: They can only be seen in the current lexical scope.

- Eric

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 3​:04 AM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Fri\, Jul 6\, 2012 at 1​:48 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

**

With state both are physically scoped as well\, though my is also dynamically scoped.

No\, state\, my and our are not dynamically scoped. They are lexically scoped​: They can only be seen in the current lexical scope.

perl -Mstrict -E"{ my $x; } $x" Global symbol "$x" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.

perl -Mstrict -E"{ state $x; } $x" Global symbol "$x" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.

perl -Mstrict -E"{ our $x; } $x" Variable "$x" is not imported at -e line 1. Global symbol "$x" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

` Eric Brine via RT wrote​:

On Fri\, Jul 6\, 2012 at 3​:04 AM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Fri\, Jul 6\, 2012 at 1​:48 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

**

With state both are physically scoped as well\, though my is also dynamically scoped.

No\, state\, my and our are not dynamically scoped. They are lexically scoped​: They can only be seen in the current lexical scope.


  'my' has dynamic scope in the it goes away at end of the physical boundaries (sans any references to it). It also dynamically is created when you enter the physical boundaries of it's lexical scope. It's a new var at that point.

Such isn't true with state or our.

p5pRT commented 11 years ago

From @demerphq

On 6 July 2012 09​:12\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Fri\, Jul 6\, 2012 at 3​:04 AM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Fri\, Jul 6\, 2012 at 1​:48 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

With state both are physically scoped as well\, though my is also dynamically scoped.

No\, state\, my and our are not dynamically scoped. They are lexically scoped​: They can only be seen in the current lexical scope.

perl -Mstrict -E"{ my $x; } $x" Global symbol "$x" requires explicit package name at -e line 1.

Execution of -e aborted due to compilation errors.

perl -Mstrict -E"{ state $x; } $x" Global symbol "$x" requires explicit package name at -e line 1.

Execution of -e aborted due to compilation errors.

perl -Mstrict -E"{ our $x; } $x" Variable "$x" is not imported at -e line 1. Global symbol "$x" requires explicit package name at -e line 1.

Execution of -e aborted due to compilation errors.

A big chunk of the confusion about our and my comes from the fact that our is not a declaration like my is. It doesnt create or reserve storage. It is a compile hint. my on the other hand is a true declaration. It actually creates stuff.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 11 years ago

From @rjbs

* Linda W \perl\-diddler@&#8203;tlinx\.org [2012-07-06T04​:30​:04]

No\, state\, my and our are not dynamically scoped. They are lexically scoped​: They can only be seen in the current lexical scope. ---- 'my' has dynamic scope in the it goes away at end of the physical boundaries (sans any references to it). It also dynamically is created when you enter the physical boundaries of it's lexical scope. It's a new var at that point.

That isn't what "dynamic scope" means here. Note especially the "and in any subroutines."

  dynamic scoping   Dynamic scoping works over a dynamic scope\, making variables   visible throughout the rest of the block in which they are first   used and in any subroutines that are called by the rest of the   block. Dynamically scoped variables can have their values   temporarily changed (and implicitly restored later) by a "local"   operator. (Compare lexical scoping.) Used more loosely to mean how   a subroutine that is in the middle of calling another subroutine   “contains” that subroutine at runtime.

This quote is from perlglossary.

-- rjbs

p5pRT commented 11 years ago

From @xdg

On Fri\, Jul 6\, 2012 at 7​:34 AM\, demerphq \demerphq@&#8203;gmail\.com wrote​:

A big chunk of the confusion about our and my comes from the fact that our is not a declaration like my is. It doesnt create or reserve storage. It is a compile hint. my on the other hand is a true declaration. It actually creates stuff.

FWIW\, I think that's just as confusing. 'our' declares an identifier\, just not one that allocates storage\, because package variables never have storage allocated by declaration\, only on demand.

-- David

p5pRT commented 11 years ago

From @demerphq

On 6 July 2012 15​:20\, David Golden \xdaveg@&#8203;gmail\.com wrote​:

On Fri\, Jul 6\, 2012 at 7​:34 AM\, demerphq \demerphq@&#8203;gmail\.com wrote​:

A big chunk of the confusion about our and my comes from the fact that our is not a declaration like my is. It doesnt create or reserve storage. It is a compile hint. my on the other hand is a true declaration. It actually creates stuff.

FWIW\, I think that's just as confusing. 'our' declares an identifier\, just not one that allocates storage\, because package variables never have storage allocated by declaration\, only on demand.

Ok\, well\, I just checked some things and I concede that I am misusing the term "declaration". I should have said "definition".

For instance see​:

http​://en.wikipedia.org/wiki/External_variable#Definition.2C_declaration_and_the_extern_keyword

\ To understand how external variables relate to the extern keyword\, it is necessary to know the difference between defining and declaring a variable. When a variable is defined\, the compiler allocates memory for that variable and possibly also initializes its contents to some value. When a variable is declared\, the compiler requires that the variable be defined elsewhere. The declaration informs the compiler that a variable by that name and type exists\, but the compiler need not allocate memory for it since it is allocated elsewhere. \

So to rephrase using that documents definition of "declaration" and "definition"​:

\ A big chunk of the confusion about our and my comes from the fact that our is not a variable definition like my is. It doesn't create or reserve storage. It is actually a declaration that acts as a compiler hint. my on the other hand is a true variable definition. It actually creates stuff. \

The point here is that dynamic variables are in fact hash/stash lookups with a special notation. They do not create anything\, they merely access the stash. Which autovivifies on use like any other hash. (And in fact scalar's are "special" as they always exist for any identifier in that namespace whether or not the scalar is ever used).

A my variable is not accessable from the stash and will not be autovivified into existence and thus requires storage allocation at compile time.

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 4​:30 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

'my' has dynamic scope

No\, it does not. Contrast with local which provides dynamic scoping​:

perl -E"sub f { say $x } { my $x = 123; f() }"

perl -E"sub f { say $x } { local $x = 123; f() }" 123

in the it goes away at end of the physical boundaries (sans any references to it).

Yes\, that's called lexical scoping. or static scoping. Did you follow the link I gave?

It also dynamically is created when you enter the physical boundaries of it's lexical scope.

Scope has nothing to do with where are variable is created. Scope is entirely about where it's visible.

You're also completely wrong about where and when it's created. A "my" variable is created at run-tine\, and either cleared or recreated on scope *exit*.

It's a new var at that point.

Yes\,

Such isn't true with state or our.

Not so. Equally new var there. A variable is an association between a name and an address. "state"\, "our"\, and "my" equally create variables.

You seem to be confusing "scope" with "allocation".

- Eric

p5pRT commented 11 years ago

From @demerphq

On 6 July 2012 17​:19\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Fri\, Jul 6\, 2012 at 4​:30 AM\, Linda W \perl\-diddler@&#8203;tlinx\.org wrote​:

'my' has dynamic scope

No\, it does not. Contrast with local which provides dynamic scoping​:

perl -E"sub f { say $x } { my $x = 123; f() }"

perl -E"sub f { say $x } { local $x = 123; f() }" 123

in the it goes away at end of the physical boundaries (sans any references to it).

Yes\, that's called lexical scoping. or static scoping. Did you follow the link I gave?

It also dynamically is created when you enter the physical boundaries of it's lexical scope.

Scope has nothing to do with where are variable is created. Scope is entirely about where it's visible.

You're also completely wrong about where and when it's created. A "my" variable is created at run-tine\, and either cleared or recreated on scope *exit*.

It's a new var at that point.

Yes\,

Such isn't true with state or our.

Not so. Equally new var there. A variable is an association between a name and an address. "state"\, "our"\, and "my" equally create variables.

our doesnt create anything.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 11​:19 AM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

You're also completely wrong about where and when it's created. A "my" variable is created at run-tine\, and either cleared or recreated on scope *exit*.

oops\, "run-tine" should be "compile-time"

To summarize​:

scope​: Where a variable is visible. Has nothing to do with allocation. lexical scoping or static scoping​: Scope known at compile-time. (e.g. my\, state\, our) dynamic scoping​: Scoping varies at run-time. (e.g. local)

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 11​:20 AM\, demerphq \demerphq@&#8203;gmail\.com wrote​:

Not so. Equally new var there. A variable is an association between a name and an address. "state"\, "our"\, and "my" equally create variables.

our doesnt create anything.

Yes it does​:

perl -E"$x = 123; package Foo; say $x"

perl -E"our $x = 123; package Foo; say $x" 123

It creates a lexically-scoped variable which is identical to $main​::x (in the above example). Remember\, a variable is an association between a name and storage. "our" does exactly that.

p5pRT commented 11 years ago

From @cpansprout

On Fri Jul 06 08​:21​:29 2012\, demerphq wrote​:

On 6 July 2012 17​:19\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

Not so. Equally new var there. A variable is an association between a name and an address. "state"\, "our"\, and "my" equally create variables.

our doesnt create anything.

At least two things​: 2) a pad slot and 3) confusion.

Oops\, I was fiddling with $[ when I wrote that. :-)

Actually\, if you look at the implementation\, you will see that our $foo actually does create a *foo GV at compile time\, if it does not already exist.

--

Father Chrysostomos

p5pRT commented 11 years ago

From [Unknown Contact. See original ticket]

On Fri Jul 06 08​:21​:29 2012\, demerphq wrote​:

On 6 July 2012 17​:19\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

Not so. Equally new var there. A variable is an association between a name and an address. "state"\, "our"\, and "my" equally create variables.

our doesnt create anything.

At least two things​: 2) a pad slot and 3) confusion.

Oops\, I was fiddling with $[ when I wrote that. :-)

Actually\, if you look at the implementation\, you will see that our $foo actually does create a *foo GV at compile time\, if it does not already exist.

--

Father Chrysostomos

p5pRT commented 11 years ago

From @demerphq

On 6 July 2012 17​:30\, Father Chrysostomos via RT \perlbug\-comment@&#8203;perl\.org wrote​:

On Fri Jul 06 08​:21​:29 2012\, demerphq wrote​:

On 6 July 2012 17​:19\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

Not so. Equally new var there. A variable is an association between a name and an address. "state"\, "our"\, and "my" equally create variables.

our doesnt create anything.

At least two things​: 2) a pad slot and 3) confusion.

Oops\, I was fiddling with $[ when I wrote that. :-)

Actually\, if you look at the implementation\, you will see that our $foo actually does create a *foo GV at compile time\, if it does not already exist.

Yes\, it will on first use\, along with almost anything that creates a symbol in a namespace\, create a GV\, which currently includes a predeclared SCALAR slot.

Which is quite different from my().

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 11 years ago

From @demerphq

On 6 July 2012 17​:40\, demerphq \demerphq@&#8203;gmail\.com wrote​:

On 6 July 2012 17​:30\, Father Chrysostomos via RT \perlbug\-comment@&#8203;perl\.org wrote​:

On Fri Jul 06 08​:21​:29 2012\, demerphq wrote​:

On 6 July 2012 17​:19\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

Not so. Equally new var there. A variable is an association between a name and an address. "state"\, "our"\, and "my" equally create variables.

our doesnt create anything.

At least two things​: 2) a pad slot and 3) confusion.

Oops\, I was fiddling with $[ when I wrote that. :-)

Actually\, if you look at the implementation\, you will see that our $foo actually does create a *foo GV at compile time\, if it does not already exist.

Yes\, it will on first use\, along with almost anything that creates a symbol in a namespace\, create a GV\, which currently includes a predeclared SCALAR slot.

Which is quite different from my().

Id like to expand on this.

I think that a lot of the confusion in this discussion comes from the fact that optimizations and bugs have broken the original model for global namespaces.

Consider Eric example. He is of the view that it shows something. I am of the view that what it shows is a bug in the implementation. "our" was introduced a replacement for "use vars" therefore I would expect it to behave the same\, but it doesn't. I would contend that this is a bug.

Recently Zefram and I debated the behavior of subs hard binding to a SPECIFIC global as an optimization\, which in turn breaks code that uses those variables and the stash has been deleted and replaced. IOW\, the late binding of the variable to the stash has in the name of optimizations been converted to an early binding\, almost as though the code was bound to a lexically allocated var.

To me a global variable is syntactic sugar for writing a fully qualified stash lookup\, and I am confident that is the meaning Larry had in mind at the beginning. You can vestigates of this that you can localize a package level scalar but not a lexically scoped scalar\, but you can localize a hash value\, or array value regardless.

So then over time optimizations without proper analysis and tests have broken some of this\, leaving the actual state of play unclear.

I would welcome a definition of these two types of variable that does not in any way rely on implementation.

When I say that "our" doesnt create anything what I mean is that the kind of creation that happens is only tenously related to the our. If any symbol of the same name already exists in the same namespace then "our" is basically a compiler hint. If the symbol doesnt exist then the our does create something\, but indirectly\, via a mechanism that is used by many codepaths.

If you contrast this to my variables (which are also newer than dynamic variables) you will see that my variables allocate an entry in a pad\, and does various other book keeping. my() is the only way that this happens.

Given the differences I think it is really foolish to consider "our" as creating something. It makes no sense as in many cases it creates nothing at all.

Anyway\, I really hope Ricardo puts some thought into this\, at a deep level\, and resists the urge to base his decisions on optimizations and new features which IMO break the original model and then gets back to us with how it SHOULD be seen and dealt with\, and then we can move on from there.

I personally will not accept any argument that is based on the current broken behavior of our as I consider the behavior of the following code to be plain and simply a bug.

package Foo; use vars qw($FOO); $FOO="FOO";

package Bar; print $FOO;

package Baz; our $BAZ;

$BAZ= "BAZ";

package Bop;

print $BAZ; __END__ BAZ

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 11 years ago

From @cpansprout

On Fri Jul 06 09​:16​:44 2012\, demerphq wrote​:

I think that a lot of the confusion in this discussion comes from the fact that optimizations and bugs have broken the original model for global namespaces.

Consider Eric example. He is of the view that it shows something. I am of the view that what it shows is a bug in the implementation. "our" was introduced a replacement for "use vars" therefore I would expect it to behave the same\, but it doesn't. I would contend that this is a bug.

Recently Zefram and I debated the behavior of subs hard binding to a SPECIFIC global as an optimization\, which in turn breaks code that uses those variables and the stash has been deleted and replaced. IOW\, the late binding of the variable to the stash has in the name of optimizations been converted to an early binding\, almost as though the code was bound to a lexically allocated var.

That optimisation has been there since perl 1. So ever since stash manipulation was added (perl 5\, I think)\, it has behaved the way it currently does.

To me a global variable is syntactic sugar for writing a fully qualified stash lookup\, and I am confident that is the meaning Larry had in mind at the beginning. You can vestigates of this that you can localize a package level scalar but not a lexically scoped scalar\, but you can localize a hash value\, or array value regardless.

So then over time optimizations without proper analysis and tests have broken some of this\, leaving the actual state of play unclear.

I would welcome a definition of these two types of variable that does not in any way rely on implementation.

Sometimes the implementation does count. In the case of $var binding to *var at compile-time\, changing that would break hundreds of CPAN modules.

When I say that "our" doesnt create anything what I mean is that the kind of creation that happens is only tenously related to the our.

Even the confusion it creates? :-)

If any symbol of the same name already exists in the same namespace then "our" is basically a compiler hint. If the symbol doesnt exist then the our does create something\, but indirectly\, via a mechanism that is used by many codepaths.

I personally will not accept any argument that is based on the current broken behavior of our as I consider the behavior of the following code to be plain and simply a bug.

Please read \http&#8203;://www\.nntp\.perl\.org/group/perl\.perl5\.porters/;msgid=200001140034\.QAA13711@&#8203;kiev\.wall\.org.

package Foo; use vars qw($FOO); $FOO="FOO";

package Bar; print $FOO;

package Baz; our $BAZ;

$BAZ= "BAZ";

package Bop;

print $BAZ; __END__ BAZ

Yves

--

Father Chrysostomos

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 12​:16 PM\, demerphq \demerphq@&#8203;gmail\.com wrote​:

Consider Eric example. He is of the view that it shows something. I am of the view that what it shows is a bug in the implementation. "our" was introduced a replacement for "use vars" therefore I would expect it to behave the same\, but it doesn't. I would contend that this is a bug.

To be clear\, I didn't not express any opinion as to what it *should* do. I didn't even know that was being discussed.

I use C\ over C\ because I can limit its scope\, so having I don't think having it do the same as C\ is a good idea.

That said\, I'm not impressed with it being able to escape the current package. That means I'd like to see​:

package AAA; # $foo is a strict error here. {   our $foo   # $foo means $AAA​::foo here } # $foo is a strict error here. our $foo # $foo means $AAA​::foo here package BBB; # $foo is a strict error here. package AAA; # Don't care whether $foo is a strict error of $AAA​::foo here.

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 4​:06 PM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

That means I'd like to see​:

package AAA; # $foo is a strict error here. { our $foo # $foo means $AAA​::foo here } # $foo is a strict error here. our $foo # $foo means $AAA​::foo here package BBB; # $foo is a strict error here.

(This is the difference from current behaviour. This doesn't re-enable the behaviour Larry Wall called buggy.)

package AAA; # Don't care whether $foo is a strict error of $AAA​::foo here.

p5pRT commented 11 years ago

From @cpansprout

On Fri Jul 06 13​:09​:49 2012\, ikegami@​adaelis.com wrote​:

On Fri\, Jul 6\, 2012 at 4​:06 PM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

That means I'd like to see​:

That’s a pity. I know it will break code. And the alternative\, \my $x = \our $x\, doesn’t work.

I would have to write\, at the top of a file​:

for my $code (our $code) { for my $this (our $this) { for my $scope(our $scope) { for my $parser(our $parser) { ....

and put this at the bottom​:

}}}}

Actually\, the piece of code I’m looking at would require eleven such topicalizers.

package AAA; # $foo is a strict error here. { our $foo # $foo means $AAA​::foo here } # $foo is a strict error here. our $foo # $foo means $AAA​::foo here package BBB; # $foo is a strict error here.

(This is the difference from current behaviour. This doesn't re-enable the behaviour Larry Wall called buggy.)

package AAA; # Don't care whether $foo is a strict error of $AAA​::foo here.

--

Father Chrysostomos

p5pRT commented 11 years ago

From [Unknown Contact. See original ticket]

On Fri Jul 06 13​:09​:49 2012\, ikegami@​adaelis.com wrote​:

On Fri\, Jul 6\, 2012 at 4​:06 PM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

That means I'd like to see​:

That’s a pity. I know it will break code. And the alternative\, \my $x = \our $x\, doesn’t work.

I would have to write\, at the top of a file​:

for my $code (our $code) { for my $this (our $this) { for my $scope(our $scope) { for my $parser(our $parser) { ....

and put this at the bottom​:

}}}}

Actually\, the piece of code I’m looking at would require eleven such topicalizers.

package AAA; # $foo is a strict error here. { our $foo # $foo means $AAA​::foo here } # $foo is a strict error here. our $foo # $foo means $AAA​::foo here package BBB; # $foo is a strict error here.

(This is the difference from current behaviour. This doesn't re-enable the behaviour Larry Wall called buggy.)

package AAA; # Don't care whether $foo is a strict error of $AAA​::foo here.

--

Father Chrysostomos

p5pRT commented 11 years ago

From @ikegami

On Fri\, Jul 6\, 2012 at 4​:43 PM\, Father Chrysostomos via RT \< perlbug-comment@​perl.org> wrote​:

On Fri Jul 06 13​:09​:49 2012\, ikegami@​adaelis.com wrote​:

On Fri\, Jul 6\, 2012 at 4​:06 PM\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

That means I'd like to see​:

That’s a pity. I know it will break code.

Yeah\, I'm sure people do rely on the behaviour that's also the source of problems. I can always dream.

p5pRT commented 11 years ago

From @rjbs

* demerphq \demerphq@&#8203;gmail\.com [2012-07-06T12​:16​:19]

I personally will not accept any argument that is based on the current broken behavior of our as I consider the behavior of the following code to be plain and simply a bug.

package Foo; use vars qw($FOO); $FOO="FOO";

package Bar; print $FOO;

package Baz; our $BAZ;

$BAZ= "BAZ";

package Bop;

print $BAZ;

What do you suggest that this code *should* do?

You think that $BAZ in the last instance should *not* find the same variable as the one to which "BAZ" was assigned\, or?

-- rjbs

p5pRT commented 11 years ago

From @cpansprout

On Thu Jul 05 18​:15​:45 2012\, doy@​tozt.net wrote​:

On Thu\, Jul 05\, 2012 at 06​:09​:17PM -0700\, Father Chrysostomos via RT wrote​:

One of my pet peeves​: I can’t use prefix ‘our’ when I use $AUTOLOAD\, because it might warn. I have to put ‘our $AUTOLOAD;’ at the top\, which is sometimes less convenient that putting it next to each use (making refactoring easier).

I completely scrambled the grammar there in trying to write it twice. I’m surprised the meaning still survived.

It should probably only warn if the second ‘our’ is in a different package.

This is in fact the opposite situation to what happens currently - there is a warning for multiple declarations in the same package\, but not if they are in different packages(​:

And\, come to think of it\, using ‘our’ in another package in the same scope is actually useful; so it shouldn’t warn.

Using ‘our’ twice in the same package is harmless. So I think the warning should simply go.

--

Father Chrysostomos

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

Father Chrysostomos via RT wrote​:

And\, come to think of it\, using ‘our’ in another package in the same scope is actually useful; so it shouldn’t warn.


Ack!

Didn't know it did that... so it warns if you use it again in same package\, but NOT if you use it in another package...even though when you use it in another package it's potentially 'random' what package it is really referring to (did you declare it first in main\, or in that second package?....er third?)

That's desirable behavior.

Personally\, I'd like to see 'our' create a package scoped variable that exists wherever the package is.

I **thought** that is what it was supposed to do.

How about .18 (req. use packaged_our;) .20 (on be default; to turn off use "no nopackaged_our";) .22-24 (deprecate no packaged and see if what the feed back is...if necessary\, leave it\, else ~.26 -- kick it).. ??

Using ‘our’ twice in the same package is harmless. So I think the warning should simply go.

p5pRT commented 11 years ago

From chromatic@wgz.org

On Friday\, July 06\, 2012 10​:43​:40 PM Linda W wrote​:

Didn't know it did that... so it warns if you use it again in same package\, but NOT if you use it in another package...even though when you use it in another package it's potentially 'random' what package it is really referring to (did you declare it first in main\, or in that second package?....er third?)

It's perfectly predictable\, just like all other lexical declarations.

Personally\, I'd like to see 'our' create a package scoped variable that exists wherever the package is.

That's effectively what vars.pm does.

How about .18 (req. use packaged_our;) .20 (on be default; to turn off use "no nopackaged_our";) .22-24 (deprecate no packaged and see if what the feed back is...if necessary\, leave it\, else ~.26 -- kick it)..

My feedback is "please don't break working code when a perfectly good mechanism already exists to do what you want". This would invent a new kind of declaration completely unlike any other declaration in Perl 5 and remove a useful existing declaration.

-- c

p5pRT commented 11 years ago

From perl-diddler@tlinx.org

chromatic via RT wrote​:

My feedback is "please don't break working code when a perfectly good mechanism already exists to do what you want". This would invent a new kind of declaration completely unlike any other declaration in Perl 5 and remove a useful existing declaration.


Perfectly good?

Your perfect maybe\,

Why not just make use vars qw(xxx) into

vars $one\, $two;

and have it be what our was supposed to be?

Then you can have your cake and vars can too!