Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perlmod doc bug wrt package scope #15625

Closed
p5pRT opened this issue Sep 24, 2016 · 41 comments
Closed

perlmod doc bug wrt package scope #15625

p5pRT opened this issue Sep 24, 2016 · 41 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 24, 2016

Migrated from rt.perl.org#129345 (status was 'resolved')

Searchable as RT129345$

@p5pRT
Copy link
Author

p5pRT commented Sep 24, 2016

From andy.glew@comp-arch.net

Created by andy@glew.net

See
http​://stackoverflow.com/questions/39668903/multiple-package-statements-in-same-file-perlmod-doc-bug?noredirect=1#comment66641669_39668903

http​://perldoc.perl.org/perlmod.html

  The package statement declares the compilation unit as being in the
  given namespace. The scope of the package declaration is from the
  declaration itself through the end of the enclosing block, eval, or
  file, whichever comes first (the same scope as the my() and local()
  operators).

Does not mention that package scope ends at next package statement.

http​://perldoc.perl.org/functions/package.html

  All unqualified dynamic identifiers in this scope will be in the
  given namespace, except where overridden by another package
  declaration

(unless you guys want to take spercial pleading, and say that in the same
file
these are all in the same "package scop[E")

  package Foo;
  my $my_var='a';

  package Bar;
  # $my_var crosses from previous package

  package Foo;

...nah - you would not do that, would you?)

Also, as you can see from the above, or from the test programs posted

http​://stackoverflow.com/questions/39668903/multiple-package-statements-in-same-file-perlmod-doc-bug?noredirect=1#comment66641669_39668903

my() variable scopes cross package statement boundaries.

Perl Info

Flags:
    category=docs
    severity=low

Site configuration information for perl 5.18.2:

Configured by root at Tue Aug 11 04:03:09 PDT 2015.

Summary of my perl5 (revision 5 version 18 subversion 2) configuration:

  Platform:
    osname=darwin, osvers=15.0, archname=darwin-thread-multi-2level
    uname='darwin osx219.apple.com 15.0 darwin kernel version 15.0.0: fri
may 22 22:03:51 pdt 2015; root:xnu-3216.0.0.1.11~1development_x86_64 x86_64
'
    config_args='-ds -e -Dprefix=/usr -Dccflags=-g  -pipe  -Dldflags=
-Dman3ext=3pm -Duseithreads -Duseshrplib -Dinc_version_list=none -Dcc=cc'
    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 ='-arch i386 -arch x86_64 -g -pipe -fno-common
-DPERL_DARWIN -fno-strict-aliasing -fstack-protector',
    optimize='-Os',
    cppflags='-g -pipe -fno-common -DPERL_DARWIN -fno-strict-aliasing
-fstack-protector'
    ccversion='', gccversion='4.2.1 Compatible Apple LLVM 7.0.0
(clang-700.0.59.1)', 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 -mmacosx-version-min=10.11.3', ldflags ='-arch i386 -arch x86_64
-fstack-protector'
    libpth=/usr/lib /usr/local/lib
    libs=
    perllibs=
    libc=, so=dylib, useshrplib=true, libperl=libperl.dylib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-arch i386 -arch x86_64 -bundle -undefined
dynamic_lookup -fstack-protector'

Locally applied patches:
    /Library/Perl/Updates/<version> comes before system perl directories
    installprivlib and installarchlib points to the Updates directory


@INC for perl 5.18.2:
    /Users/glew/perl5/lib/perl5/5.18.2/darwin-thread-multi-2level
    /Users/glew/perl5/lib/perl5/5.18.2
    /Users/glew/perl5/lib/perl5/darwin-thread-multi-2level
    /Users/glew/perl5/lib/perl5
    /Library/Perl/5.18/darwin-thread-multi-2level
    /Library/Perl/5.18
    /Network/Library/Perl/5.18/darwin-thread-multi-2level
    /Network/Library/Perl/5.18
    /Library/Perl/Updates/5.18.2
    /System/Library/Perl/5.18/darwin-thread-multi-2level
    /System/Library/Perl/5.18
    /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level
    /System/Library/Perl/Extras/5.18
    .


Environment for perl 5.18.2:
    DYLD_LIBRARY_PATH (unset)
    HOME=/Users/glew
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)

PATH=/Users/glew/perl5/bin:/Users/glew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
    PERL5LIB=/Users/glew/perl5/lib/perl5
    PERL_BADLANG (unset)
    PERL_LOCAL_LIB_ROOT=/Users/glew/perl5
    PERL_MB_OPT=--install_base "/Users/glew/perl5"
    PERL_MM_OPT=INSTALL_BASE=/Users/glew/perl5
    SHELL=/bin/bash


You have finished composing your message. At this point, you have
a few options. You can:

    * [Se]nd the message to perlbug@perl.org,
    * [D]isplay the message on the screen,
    * [R]e-edit the message
    * Display or change the message's [su]bject
    * Save the message to a [f]ile to mail at another time
    * [Q]uit without sending a message

@p5pRT
Copy link
Author

p5pRT commented Sep 24, 2016

From zefram@fysh.org

via RT wrote​:

Does not mention that package scope ends at next package statement.

It doesn't​: the next package statement produces a nested package scope.
The two scopes happen to have the same end point, so it's just a bit
difficult to discern.

my() variable scopes cross package statement boundaries.

Nested again. You have a package scope inside a my scope inside a
package scope.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Sep 24, 2016

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

@p5pRT
Copy link
Author

p5pRT commented Sep 25, 2016

From @davidnicol

thanks for this explanation! I too thought package replaced rather
than nested, and I was surprised to see this output​:

$ perl -le 'package a; { print __PACKAGE__; package b; print
__PACKAGE__; } print __PACKAGE__;'
a
b
a

I was expecting a, b, b. Was it initially broken, like in perl 5.0.0?

Anyway, some kind of improvement to the documentation of this makes
sense as it currently can be misinterpreted.

dln

On Sat, Sep 24, 2016 at 4​:56 PM, Zefram <zefram@​fysh.org> wrote​:

via RT wrote​:

Does not mention that package scope ends at next package statement.

It doesn't​: the next package statement produces a nested package scope.
The two scopes happen to have the same end point, so it's just a bit
difficult to discern.

my() variable scopes cross package statement boundaries.

Nested again. You have a package scope inside a my scope inside a
package scope.

-zefram

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Nov 19, 2016

From @jkeenan

On Sun, 25 Sep 2016 01​:22​:39 GMT, davidnicol@​gmail.com wrote​:

thanks for this explanation! I too thought package replaced rather
than nested, and I was surprised to see this output​:

$ perl -le 'package a; { print __PACKAGE__; package b; print
__PACKAGE__; } print __PACKAGE__;'
a
b
a

I was expecting a, b, b. Was it initially broken, like in perl 5.0.0?

Anyway, some kind of improvement to the documentation of this makes
sense as it currently can be misinterpreted.

dln

In order to move this ticket toward resolution, I am proposing the attached patch to pod/perlmod.pod. Please review. I'll apply to blead within 7 days if there are no objections.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Nov 19, 2016

From @jkeenan

129345-0001-Explain-complications-of-multiple-packages-within-a-.patch
From 4c6f8b6765a6d3c2681ec6754407ecae0a416834 Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Fri, 18 Nov 2016 19:28:41 -0500
Subject: [PATCH] Explain complications of multiple packages within a file.

Provide two examples with dynamic- and lexically-scoped variables.  In one,
the second package declaration is made within a BLOCK.  In the other, not
within a BLOCK.

For: RT #129345
---
 pod/perlmod.pod | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 90 insertions(+), 3 deletions(-)

diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 0ed4bd9..6e3ec9b 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@@ -30,15 +30,15 @@ X<package> X<namespace> X<variable, global> X<global variable> X<global>
 
 Perl provides a mechanism for alternative namespaces to protect
 packages from stomping on each other's variables.  In fact, there's
-really no such thing as a global variable in Perl.  The package
+really no such thing as a global variable in Perl.  The C<package>
 statement declares the compilation unit as being in the given
-namespace.  The scope of the package declaration is from the
+namespace.  The scope of the C<package> declaration is from the
 declaration itself through the end of the enclosing block, C<eval>,
 or file, whichever comes first (the same scope as the my() and
 local() operators).  Unqualified dynamic identifiers will be in
 this namespace, except for those few identifiers that if unqualified,
 default to the main package instead of the current one as described
-below.  A package statement affects only dynamic variables--including
+below.  A C<package> statement affects only dynamic variables--including
 those you've used local() on--but I<not> lexical variables created
 with my().  Typically it would be the first declaration in a file
 included by the C<do>, C<require>, or C<use> operators.  You can
@@ -106,6 +106,93 @@ The special symbol C<__PACKAGE__> contains the current package, but cannot
 See L<perlsub> for other scoping issues related to my() and local(),
 and L<perlref> regarding closures.
 
+=head3 Multiple Packages within a File
+
+You can have more than one C<package> declaration in a file -- but it's
+tricky.  Dynamically-scoped variables and subroutines are declared within the
+current package, but lexically-scoped (C<my>, C<our>, C<state>) are not.
+Consequently, you have to pay careful attention to which package is "current".
+Consider the following two programs:
+
+=over 4
+
+=item 1 Package declaration within a block
+
+    use strict; no strict 'vars'; use warnings;
+
+    package a;                                          # [package declaration]
+
+    sub foo { print "Hello world\n"; }                  # [Dynamically scoped to package 'a']
+    @apples = ('gala', 'jazz', 'cortland');             # [Dynamically scoped to package 'a']
+    my @oranges = ('valencia', 'navel', 'mandarin');    # [Not dynamically scoped]
+
+    {
+        print __PACKAGE__, "\n";                        # a
+        foo();                                          # Hello world
+        print "1:  @apples\n";                          # 1:  gala jazz cortland
+        print "1:  @oranges\n";                         # 1:  valencia navel mandarin
+
+        package b;                                      # [package declaration (within BLOCK)]
+
+        print __PACKAGE__, "\n";                        # b
+        a::foo();                                       # Hello world
+        print "2:  @apples\n";                          # 2:
+        print "2:  @oranges\n";                         # 2:  valencia navel mandarin
+        print "2a: @a::apples\n";                       # 2a: gala jazz cortland
+        sub bar { print "Goodbye world\n"; }            # [Dynamically scoped to package 'b']
+        bar();                                          # Goodbye world
+    }                                                   # [End of BLOCK closes scope of package 'b']
+
+                                                        # ['a' is once again current package]
+    print __PACKAGE__, "\n";                            # a
+    foo();                                              # Hello world
+    print "3:  @apples\n";                              # 3:  gala jazz cortland
+    print "3:  @oranges\n";                             # 3:  valencia navel mandarin
+                                                        # [We can call bar()
+                                                        #  provided it's fully qualified]
+    b::bar();                                           # Goodbye world
+
+=item 2 Package declaration not within a block
+
+    use strict; no strict 'vars'; use warnings;
+
+    package a;                                          # [package declaration]
+    print __PACKAGE__, "\n";                            # a
+
+    sub foo { print "Hello world\n"; }                  # [Dynamically scoped to package 'a']
+    foo();                                              # Hello world
+
+    @apples = ('gala', 'jazz', 'cortland');             # [Dynamically scoped to package 'a']
+    print "1:  @apples\n";                              # 1:  gala jazz cortland
+
+    my @oranges = ('valencia', 'navel', 'mandarin');    # [Not dynamically scoped]
+    print "1:  @oranges\n";                             # 1:  valencia navel mandarin
+
+
+    package b;                                          # [package declaration]
+    print __PACKAGE__, "\n";                            # b
+
+    sub bar { print "Goodbye world\n"; }                # [Dynamically scoped to package 'b']
+    bar();                                              # Goodbye world
+
+    { local $@; eval { foo(); }; print "<$@>\n"; }      # [foo() not fully qualified;
+                                                        #  dies with exception]
+                                                        # Undefined subroutine &b::foo called ...
+
+                                                        # [We can call foo()
+                                                        #  provided it's fully qualified]
+    a::foo();                                           # Hello world
+
+    print "2:  @apples\n";                              # 2:
+                                                        # [Warnings]
+                                                        # Possible unintended interpolation ...
+                                                        # Name "b::apples" used only once: ...
+
+    print "2a: @a::apples\n";                           # 2a: gala jazz cortland
+    print "2:  @oranges\n";                             # 2:  valencia navel mandarin
+
+=back
+
 =head2 Symbol Tables
 X<symbol table> X<stash> X<%::> X<%main::> X<typeglob> X<glob> X<alias>
 
-- 
2.7.4

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2016

From @iabyn

On Fri, Nov 18, 2016 at 04​:34​:16PM -0800, James E Keenan via RT wrote​:

On Sun, 25 Sep 2016 01​:22​:39 GMT, davidnicol@​gmail.com wrote​:

thanks for this explanation! I too thought package replaced rather
than nested, and I was surprised to see this output​:

$ perl -le 'package a; { print __PACKAGE__; package b; print
__PACKAGE__; } print __PACKAGE__;'
a
b
a

I was expecting a, b, b. Was it initially broken, like in perl 5.0.0?

Anyway, some kind of improvement to the documentation of this makes
sense as it currently can be misinterpreted.

dln

In order to move this ticket toward resolution, I am proposing the
attached patch to pod/perlmod.pod. Please review. I'll apply to blead
within 7 days if there are no objections.

I think that contains far to much detail and will just tend to confuse
rather than enlighten. Personally I think the current docs are fine as
they are.

--
The Enterprise is captured by a vastly superior alien intelligence which
does not put them on trial.
  -- Things That Never Happen in "Star Trek" #10

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2016

From @jkeenan

On Mon, 21 Nov 2016 09​:51​:08 GMT, davem wrote​:

On Fri, Nov 18, 2016 at 04​:34​:16PM -0800, James E Keenan via RT wrote​:

On Sun, 25 Sep 2016 01​:22​:39 GMT, davidnicol@​gmail.com wrote​:

thanks for this explanation! I too thought package replaced rather
than nested, and I was surprised to see this output​:

$ perl -le 'package a; { print __PACKAGE__; package b; print
__PACKAGE__; } print __PACKAGE__;'
a
b
a

I was expecting a, b, b. Was it initially broken, like in perl 5.0.0?

Anyway, some kind of improvement to the documentation of this makes
sense as it currently can be misinterpreted.

dln

In order to move this ticket toward resolution, I am proposing the
attached patch to pod/perlmod.pod. Please review. I'll apply to blead
within 7 days if there are no objections.

I think that contains far to much detail and will just tend to confuse
rather than enlighten. Personally I think the current docs are fine as
they are.

Which I can understand. List​: other opinions?

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2016

From zefram@fysh.org

Dave Mitchell wrote​:

                  Personally I think the current docs are fine as

they are.

I concur. The critical part of the documentation is

  The scope of the package declaration is from the declaration itself
  through the end of the enclosing block, eval, or file, whichever
  comes first (the same scope as the my() and local() operators).

which is perfectly explicit and clear.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2016

From @davidnicol

On Tue, Nov 22, 2016 at 11​:20 PM, Zefram <zefram@​fysh.org> wrote​:

Dave Mitchell wrote​:

                  Personally I think the current docs are fine as

they are.

I concur. The critical part of the documentation is

The scope of the package declaration is from the declaration itself
through the end of the enclosing block\, eval\, or file\, whichever
comes first \(the same scope as the my\(\) and local\(\) operators\)\.

which is perfectly explicit and clear.

-zefram

Saying "package" has the same scope as "my" can be read as implying
that outer packages are still part of what is called the "scope chain"
in the ECMA-262 standard, so that

  package a; @​apples = qw/gala fuji/ ; { package b; print "@​apples" }

should print "galafuji."

  Perl provides a mechanism for alternative namespaces to protect packages
  from stomping on each other's variables. In fact, there's really no such
  thing as a global variable in Perl. The package statement declares the
  compilation unit as being in the given namespace. The scope of the package
  declaration is from the declaration itself through the end of the
  enclosing block, "eval", or file, whichever comes first (the same scope as
  the my() and local() operators). Unqualified dynamic identifiers will be
  in this namespace, except for those few identifiers that if unqualified,
  default to the main package instead of the current one as described below.
  A package statement affects only dynamic variables--including those you've
  used local() on--but not lexical variables created with my(). Typically it
  would be the first declaration in a file included by the "do", "require",
  or "use" operators. You can switch into a package in more than one place;
  it merely influences which symbol table is used by the compiler for the
  rest of that block. You can refer to variables and filehandles in other
  packages by prefixing the identifier with the package name and a double
  colon​: $Package​::Variable. If the package name is null, the "main" package
  is assumed. That is, $​::sail is equivalent to $main​::sail.

Also, what's up with this "In fact, there's really no such thing as a
global variable in Perl" assertion? We're in the middle
of describing Perl's global variables here. Also, "our" should get
mentioned along with "my."

I submit this rewrite​:

  Perl provides a mechanism for alternative namespaces to protect packages
  from stomping on each other's dynamic variables. The package statement
  instructs the compiler as to which namespace to look up unqualified
  dynamic variable and subroutine names in. The scope of the package
  declaration is from the declaration itself through the end of the
  enclosing block, "eval", or file, whichever comes first (the same scope as
  the my() and local() operators), after which the namespace returns to what
  it was previously. Unqualified dynamic identifiers will be in this
  namespace, except for those few identifiers that if unqualified, default
  to the main package instead of the current one as described below. A
  package statement affects only dynamic variables--including those you've
  used local() on--but not lexical variables created with my() or the
  lexical aliases created with our(). Typically "package" is the first
  declaration in a file included by the "do", "require", or "use" operators.
  You can switch into a package in more than one place​: "package" merely
  specifies which symbol table is used by the compiler for the rest of that
  block, or until the next "package" statement. You can refer to variables
  and filehandles in other packages by prefixing the identifier with the
  package name and a double colon​: $Package​::Variable. If the package name
  is null, the "main" package is assumed. That is, $​::sail is equivalent to
  $main​::sail.

patch attached.

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2016

From @davidnicol

Inline Patch
--- ./5.24/pods/perlmod.pod	2016-05-11 11:20:26.000000000 -0500
+++ ./dln/pods/perlmod.pod	2016-11-23 00:20:35.000000000 -0600
@@ -29,22 +29,25 @@
 X<package> X<namespace> X<variable, global> X<global variable> X<global>
 
 Perl provides a mechanism for alternative namespaces to protect
-packages from stomping on each other's variables.  In fact, there's
-really no such thing as a global variable in Perl.  The package
-statement declares the compilation unit as being in the given
-namespace.  The scope of the package declaration is from the
+packages from stomping on each other's dynamic variables. The package
+statement instructs the compiler as to which namespace to look up unqualified
+dynamic variable and subroutine names in.
+The scope of the package declaration is from the
 declaration itself through the end of the enclosing block, C<eval>,
 or file, whichever comes first (the same scope as the my() and
-local() operators).  Unqualified dynamic identifiers will be in
+local() operators), after which the namespace returns to what it was previously.
+Unqualified dynamic identifiers will be in
 this namespace, except for those few identifiers that if unqualified,
 default to the main package instead of the current one as described
 below.  A package statement affects only dynamic variables--including
 those you've used local() on--but I<not> lexical variables created
-with my().  Typically it would be the first declaration in a file
+with my() or the lexical aliases created with our().
+Typically C<package> is the first declaration in a file
 included by the C<do>, C<require>, or C<use> operators.  You can
-switch into a package in more than one place; it merely influences
+switch into a package in more than one place: C<package> merely specifies
 which symbol table is used by the compiler for the rest of that
-block.  You can refer to variables and filehandles in other packages
+block, or until the next C<package> statement.
+You can refer to variables and filehandles in other packages
 by prefixing the identifier with the package name and a double
 colon: C<$Package::Variable>.  If the package name is null, the
 C<main> package is assumed.  That is, C<$::sail> is equivalent to

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2016

From zefram@fysh.org

David Nicol wrote​:

Saying "package" has the same scope as "my" can be read as implying
that outer packages are still part of what is called the "scope chain"
in the ECMA-262 standard,

They are. The scopes are nested.

 package a; @&#8203;apples = qw/gala fuji/ ; \{ package b; print "@&#8203;apples" \}

should print "galafuji."

No. The closest enclosing scope takes precedence, as usual. This is no
different from lexical variables of the same name shadowing one another.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2016

From @davidnicol

yes, of course, that's how it works, and it looks to me like you can't
see that it can be misread this way, because you know how it works.

The fact that there is exactly one active default namespace at any
time is not spelled out in the documentation.

The packages active in the outer block are *not* active in the inner
block. The inner block is in the inner package. Were C<package> to do
what the documentation can be incorrectly read to say it does,
C<package> would put a namespace at the head of a list of namespaces
that are to be searched for dynamic symbols. That is not what happens,
of course, but the current docs can be read to give that idea.

By changing

  The package statement declares the compilation unit as being in
the given namespace.

to

  The package statement instructs the compiler as to which namespace
to look up unqualified dynamic variable and subroutine names in.

I hope to make it clear that there is exactly one namespace (singular)
where symbols are looked up in, while avoiding scary jargon (declares
the compilation unit) that isn't well defined and might not be used
correctly. Do we use "compilation unit" elsewhere? are all blocks
compilation units? if a package statement affects at a compilation
unit granularity, how can it be used to change namespace in the middle
of a block?

"being in the given namespace" doesn't make it clear that there is
only one namespace active for any statement. The fact that __PACKAGE__
is a scalar and not an array helps but might not convince somebody
coming from a "scope chain theory" background who takes the scalar
nature of __PACKAGE__ to mean that __PACKAGE__ provides the innermost
namespace.

Do any twenty-somethings still learn Perl, anyway?

On Wed, Nov 23, 2016 at 12​:58 AM, Zefram <zefram@​fysh.org> wrote​:

David Nicol wrote​:

Saying "package" has the same scope as "my" can be read as implying
that outer packages are still part of what is called the "scope chain"
in the ECMA-262 standard,

They are. The scopes are nested.

 package a; @&#8203;apples = qw/gala fuji/ ; \{ package b; print "@&#8203;apples" \}

should print "galafuji."

No. The closest enclosing scope takes precedence, as usual. This is no
different from lexical variables of the same name shadowing one another.

-zefram

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2016

From zefram@fysh.org

David Nicol wrote​:

The fact that there is exactly one active default namespace at any
time is not spelled out in the documentation.

OK, that's a clarification worth making.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2016

From andy.glew@comp-arch.net

Fair enough - package and my (and probably other, like our, etc.) start new
nested scopes, and remain in scope until their scope ends.

Q​: is there anywhere mentioned what things end such a scope?

The only things that I am aware of are } and file boundaries.

On Sat, Sep 24, 2016 at 2​:57 PM, Zefram via RT <perlbug-followup@​perl.org>
wrote​:

via RT wrote​:

Does not mention that package scope ends at next package statement.

It doesn't​: the next package statement produces a nested package scope.
The two scopes happen to have the same end point, so it's just a bit
difficult to discern.

my() variable scopes cross package statement boundaries.

Nested again. You have a package scope inside a my scope inside a
package scope.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2016

From andy.glew@comp-arch.net

All of my last message boils down to

"In Perl, packages do not nest in terms of structure. But package scopes
do nest, albeit invisibly and uselessly."

The content of this message is my personal opinion only. Although I am an
employee (currently of MIPS Technologies; in the past of companies such as
Intellectual Properties, Intel, AMD, Motorola, and Gould), I reveal this
only so that the reader may account for any possible bias I may have
towards my employer's products. The statements I make here in no way
represent my employer's position on the issue, nor am I authorized to speak
on behalf of my employer.

On Wed, Nov 23, 2016 at 11​:15 AM, <andy.glew@​comp-arch.net> wrote​:

@​Zefram​: I am fine on what you say about "The [package] scopes are nested.
... The closest enclosing scope takes precedence, as usual. This is no different
from lexical variables of the same name shadowing one another."

This makes sense.

I am tempted to say "Where do the manuals say this?" But that is pushing
it - nobody expects the Perl manuals to be clear (where "clear" means "free
of surprises').

I do point out that those of us who run with 'use warnings' are used to
having 'lexical variables of the same name shadowing each other'.

% perl -e 'use warnings; my $a=1; my $a=2; print $a;'
"my" variable $a masks earlier declaration in same scope at -e line 1.
2

so the behavior of package is not exactly the same as lexical variables of
the same name - at least not wrt warnings. But then warnings are an
optional part of Perl.

(No, I am not suggesting that 'package A; package A', i.e. two successive
uses of the same package name shadowing each other give a warning. They
are not creating two different packages​: they are just activating the same
package namespace, redundantly and in a nested manner.)

I think that my main confusion was thinking that "nested package scopes"
might imply that one package was nested within the other. As in C++, where
'class A { ... class B { ... } }' creates classes A and A​::B. But in
Perl packages are not really nested in terms of type structure; 'package A;
... package B; ...' does not create nested package A​::B, it creates
packages A and B, where the lexical scope of B is supposedly nested within
the lexical scope of A.

I say "supposedly nested" because ... is there any way that you can tell
the difference between 'package A; ... package B; ...' with such scoping,
and the following with a hypothetical "end package scope" declaration -
'package A; ... end_package A; package B; ... end package B' ?

(Where the hypothetical 'end_package' does not affect my variable scopes -
it just removes the current package A from the stack of nested scopes.)

I don't think there is such a way to distinguish such nesting. Which is
fine​: it is a distinction without a consequence, i.e. it is meaningless.
Just a convention.

The content of this message is my personal opinion only. Although I am an
employee (currently of MIPS Technologies; in the past of companies such as
Intellectual Properties, Intel, AMD, Motorola, and Gould), I reveal this
only so that the reader may account for any possible bias I may have
towards my employer's products. The statements I make here in no way
represent my employer's position on the issue, nor am I authorized to speak
on behalf of my employer.

On Tue, Nov 22, 2016 at 10​:58 PM, Zefram via RT <perlbug-followup@​perl.org

wrote​:

David Nicol wrote​:

Saying "package" has the same scope as "my" can be read as implying
that outer packages are still part of what is called the "scope chain"
in the ECMA-262 standard,

They are. The scopes are nested.

 package a; @&#8203;apples = qw/gala fuji/ ; \{ package b; print "@&#8203;apples" \}

should print "galafuji."

No. The closest enclosing scope takes precedence, as usual. This is no
different from lexical variables of the same name shadowing one another.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2016

From andy.glew@comp-arch.net

@​Zefram​: I am fine on what you say about "The [package] scopes are nested.
... The closest enclosing scope takes precedence, as usual. This is no
different
from lexical variables of the same name shadowing one another."

This makes sense.

I am tempted to say "Where do the manuals say this?" But that is pushing
it - nobody expects the Perl manuals to be clear (where "clear" means "free
of surprises').

I do point out that those of us who run with 'use warnings' are used to
having 'lexical variables of the same name shadowing each other'.

% perl -e 'use warnings; my $a=1; my $a=2; print $a;'
"my" variable $a masks earlier declaration in same scope at -e line 1.
2

so the behavior of package is not exactly the same as lexical variables of
the same name - at least not wrt warnings. But then warnings are an
optional part of Perl.

(No, I am not suggesting that 'package A; package A', i.e. two successive
uses of the same package name shadowing each other give a warning. They
are not creating two different packages​: they are just activating the same
package namespace, redundantly and in a nested manner.)

I think that my main confusion was thinking that "nested package scopes"
might imply that one package was nested within the other. As in C++, where
'class A { ... class B { ... } }' creates classes A and A​::B. But in
Perl packages are not really nested in terms of type structure; 'package A;
... package B; ...' does not create nested package A​::B, it creates
packages A and B, where the lexical scope of B is supposedly nested within
the lexical scope of A.

I say "supposedly nested" because ... is there any way that you can tell
the difference between 'package A; ... package B; ...' with such scoping,
and the following with a hypothetical "end package scope" declaration -
'package A; ... end_package A; package B; ... end package B' ?

(Where the hypothetical 'end_package' does not affect my variable scopes -
it just removes the current package A from the stack of nested scopes.)

I don't think there is such a way to distinguish such nesting. Which is
fine​: it is a distinction without a consequence, i.e. it is meaningless.
Just a convention.

The content of this message is my personal opinion only. Although I am an
employee (currently of MIPS Technologies; in the past of companies such as
Intellectual Properties, Intel, AMD, Motorola, and Gould), I reveal this
only so that the reader may account for any possible bias I may have
towards my employer's products. The statements I make here in no way
represent my employer's position on the issue, nor am I authorized to speak
on behalf of my employer.

On Tue, Nov 22, 2016 at 10​:58 PM, Zefram via RT <perlbug-followup@​perl.org>
wrote​:

David Nicol wrote​:

Saying "package" has the same scope as "my" can be read as implying
that outer packages are still part of what is called the "scope chain"
in the ECMA-262 standard,

They are. The scopes are nested.

 package a; @&#8203;apples = qw/gala fuji/ ; \{ package b; print "@&#8203;apples" \}

should print "galafuji."

No. The closest enclosing scope takes precedence, as usual. This is no
different from lexical variables of the same name shadowing one another.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2016

From @demerphq

On 23 November 2016 at 21​:25, David Nicol <davidnicol@​gmail.com> wrote​:

yes, of course, that's how it works, and it looks to me like you can't
see that it can be misread this way, because you know how it works.

The fact that there is exactly one active default namespace at any
time is not spelled out in the documentation.

The packages active in the outer block are *not* active in the inner
block. The inner block is in the inner package. Were C<package> to do
what the documentation can be incorrectly read to say it does,
C<package> would put a namespace at the head of a list of namespaces
that are to be searched for dynamic symbols. That is not what happens,
of course, but the current docs can be read to give that idea.

By changing

The package statement declares the compilation unit as being in

the given namespace.

to

The package statement instructs the compiler as to which namespace

to look up unqualified dynamic variable and subroutine names in.

I hope to make it clear that there is exactly one namespace (singular)
where symbols are looked up in, while avoiding scary jargon (declares
the compilation unit) that isn't well defined and might not be used
correctly. Do we use "compilation unit" elsewhere?

I think so.

are all blocks compilation units?

I would not say so. I would say compilation unit is something akin to
"statement", but includes the use of eval TEXT and do BLOCK, do FILE,
and etc.

if a package statement affects at a compilation
unit granularity, how can it be used to change namespace in the middle
of a block?

Because compilation unit includes the statement.

I think the documentation should say something like

"the package statement determines the namespace for unqualified global
variables and subroutines used or declared after it in the same
lexical scope."

that is, it should make it clear that it is lexically scoped, and it
should make clear that it affects the declaration of things as well as
their reference.

Also, I would avoid the term dynamic variables in favour of the term
global variables. I don't think it helps introducing an orthagonal
concept to the discussion, especially when dynamic scoping is not
restricted to global variables, but package is.

"being in the given namespace" doesn't make it clear that there is
only one namespace active for any statement.

I disagree. While I am fine with you rewording it, I think the use of
the singular there is very clear.

Some of your other criticisms are more compelling. "compilation unit"
is not a great term.

I wonder if we should use the term "namespace" at all or if we do if
we should document the relationship between namespaces and nested
hashes.

I guess some of the problem here comes from the fact that the package
variable is lexically scoped, but the property it affects is the rule
for global variable lookup. :-)

Yves

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2016

From @davidnicol

On Thu, Nov 24, 2016 at 4​:12 AM, demerphq <demerphq@​gmail.com> wrote​:

are all blocks compilation units?

I would not say so. I would say compilation unit is something akin to
"statement", but includes the use of eval TEXT and do BLOCK, do FILE,
and etc.

if a package statement affects at a compilation
unit granularity, how can it be used to change namespace in the middle
of a block?

Because compilation unit includes the statement.

We (you and I) appear to be in agreement in favor of concerning
removing "compilation unit" from this document.

I think the documentation should say something like

"the package statement determines the namespace for unqualified global
variables and subroutines used or declared after it in the same
lexical scope."

that is, it should make it clear that it is lexically scoped, and it
should make clear that it affects the declaration of things as well as
their reference.

Works for me

Also, I would avoid the term dynamic variables in favour of the term
global variables. I don't think it helps introducing an orthagonal
concept to the discussion, especially when dynamic scoping is not
restricted to global variables, but package is.

Have you any explanation of where the "in fact, Perl has no such thing
as global variables" business, that I struck in my draft patch, came
from? In my parlance, package a/k/a dynamic a/k/a symbol table a/k/a
"global" variables are all the same thing in Perl, and the only thing
C<package> does is specify where unqualified ones go.

"being in the given namespace" doesn't make it clear that there is
only one namespace active for any statement.

I disagree. While I am fine with you rewording it, I think the use of
the singular there is very clear.

Wouldn't make it clear to my hypothetical thick-skulled person who
insists on imagining that "nested packages" means unqualified names
not defined in the inner package will resolve to their defined
co-nominees in the outer.

Some of your other criticisms are more compelling. "compilation unit"
is not a great term.

I wonder if we should use the term "namespace" at all or if we do if
we should document the relationship between namespaces and nested
hashes.

how about "prefix" ?

I guess some of the problem here comes from the fact that the package
variable is lexically scoped, but the property it affects is the rule
for global variable lookup. :-)

There you go again with the global variables. In fact there is no such
thing in Perl, haven't you read the documentation? <g/>

Yves

dln

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Nov 24, 2016

From @demerphq

On 24 November 2016 at 18​:20, David Nicol <davidnicol@​gmail.com> wrote​:

On Thu, Nov 24, 2016 at 4​:12 AM, demerphq <demerphq@​gmail.com> wrote​:

are all blocks compilation units?

I would not say so. I would say compilation unit is something akin to
"statement", but includes the use of eval TEXT and do BLOCK, do FILE,
and etc.

if a package statement affects at a compilation
unit granularity, how can it be used to change namespace in the middle
of a block?

Because compilation unit includes the statement.

We (you and I) appear to be in agreement in favor of concerning
removing "compilation unit" from this document.

I definitely think documentation that explains what is going on
without using that term is to be preferred over documentation that
does use it. So yes. :-)

I think the documentation should say something like

"the package statement determines the namespace for unqualified global
variables and subroutines used or declared after it in the same
lexical scope."

that is, it should make it clear that it is lexically scoped, and it
should make clear that it affects the declaration of things as well as
their reference.

Works for me

Also, I would avoid the term dynamic variables in favour of the term
global variables. I don't think it helps introducing an orthagonal
concept to the discussion, especially when dynamic scoping is not
restricted to global variables, but package is.

Have you any explanation of where the "in fact, Perl has no such thing
as global variables" business, that I struck in my draft patch, came
from? In my parlance, package a/k/a dynamic a/k/a symbol table a/k/a
"global" variables are all the same thing in Perl, and the only thing
C<package> does is specify where unqualified ones go.

It was introduced in 5.001. So soon after the introduction of
lexically scoped variables and the switch from Perl 4 namespace
management to Perl 5 management.

commit 748a930
Author​: Larry Wall <lwall@​netlabs.com>
Date​: Sun Mar 12 22​:32​:14 1995 -0800

  Perl 5.001

  [See the Changes file for a list of changes]

Inline Patch
diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index d804b1e..dc825d6 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@@ -6,8 +6,10 @@ perlmod - Perl modules (packages)

 =head2 Packages

-Perl provides a mechanism for alternate namespaces to protect packages
-from stomping on each others variables.  By default, a Perl script starts
+Perl provides a mechanism for alternative namespaces to protect packages
+from stomping on each others variables.  In fact, apart from certain magical
+variables, there's really no such thing as a global variable in Perl.
+By default, a Perl script starts
 compiling into the package known as C<main>.  You can switch namespaces
 using the C<package> declaration.  The scope of the package declaration is
 from the declaration itself to the end of the enclosing block (the same

Which when i compare it to now:

Perl provides a mechanism for alternative namespaces to protect
packages from stomping on each other's variables. In fact, there's
really no such thing as a global variable in Perl. The package
statement declares the compilation unit as being in the given
namespace. The scope of the package declaration is from the
declaration itself through the end of the enclosing block, C<eval>,

reads (to me) slightly differently. The original sentence reads

"In fact, apart from certain magical variables, there's really no such
thing as a global variable in Perl."

which to me, combined with the context established by the preceding
sentence, clearly refers to the fact that all non-lexical vars (my
vars) are in a specific package.

In the modern version it reads

"In fact, there's really no such thing as a global variable in Perl."

The reference to certain magic variables (which are forced to main),
has been removed, and with it the context that we are talking about
which namespace vars are in. The way I read the original language
suggests to me that Perl 4, which I have never used, had a single
namespace.

Regardless the entire opening paragraph of perlmod reads to me like it
was written for someone migrating from Perl 4, and it should be
rewritten completely as if it were going to be read by
someone who had never used perl, (or used only used "modern" perl's)
would understand.

"being in the given namespace" doesn't make it clear that there is
only one namespace active for any statement.

I disagree. While I am fine with you rewording it, I think the use of
the singular there is very clear.

Wouldn't make it clear to my hypothetical thick-skulled person who
insists on imagining that "nested packages" means unqualified names
not defined in the inner package will resolve to their defined
co-nominees in the outer.

I am fine with rewording it, I just wanted to be clear I think that it
was unambiguous, and thus if you change it we need to preserve the
original meaning (which you were going to do , but anyway).

Some of your other criticisms are more compelling. "compilation unit"
is not a great term.

I wonder if we should use the term "namespace" at all or if we do if
we should document the relationship between namespaces and nested
hashes.

how about "prefix" ?

Yeah, I thought of that, but it doesn't do it for me.

I guess some of the problem here comes from the fact that the package
variable is lexically scoped, but the property it affects is the rule
for global variable lookup. :-)

There you go again with the global variables. In fact there is no such
thing in Perl, haven't you read the documentation? <g/>

:-)

Lets get rid of that language. :-)

cheers,
Yves

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

@p5pRT
Copy link
Author

p5pRT commented Dec 2, 2016

From @jkeenan

David, would you be able to submit a revised version of your Nov 23 patch that (a) is drawn against perl 5 blead; and (b) takes into account the discussion between you and Yves and others?

For myself​: +1 to eliminating the term "compilation unit"; +1 to eliminating mention of "magic variables".

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @davidnicol

commit a470df252293d4dc0aa3264022edf72e5a147d91
can be pulled from
https://github.com/davidnicol/perl

Here's my revised opening paragraph​:

Unlike Perl 4, in which all the variables were dynamic and shared one
global name space, causing maintainability problems, Perl 5 provides two
mechanisms for protecting code from having its variables stomped on by
other code​: lexical variables created with C<my>, C<our> or C<state> and
the C<package> declaration which instructs the compiler as to which
namespace to prefix to unqualified dynamic names, which both protects
against accidental stomping and provides an interface for deliberately
clobbering global dynamic variables declared and used in other scopes or
packages, when that is what you want to do. The scope of the package
declaration is from the declaration itself through the end of the
enclosing block, C<eval>, or file, whichever comes first (the same scope
as the my(), our(), state(), and local() operators, and also the effect
of the experimental "reference aliasing," which may change), or until
the next C<package> declaration. Unqualified dynamic identifiers will
be in this namespace, except for those few identifiers that, if
unqualified, default to the main package instead of the current one as
described below. A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, but I<not> lexical variables created with my(), our() or state().
Typically it is the first declaration in a file included by the C<do>,
C<require>, or C<use> operators. You can switch into a package in more
than one place​: C<package> has no effect beyond specifying which symbol
table the compiler will use for dynamic symbols for the rest of that
block or until the next C<package> statement. You can refer to
variables and filehandles in other packages by prefixing the identifier
with the package name and a double colon​: C<$Package​::Variable>. If the
package name is null, the C<main> package is assumed. That is,
C<$​::sail> is equivalent to C<$main​::sail>.

Also I added the last sentence in

Packages may themselves contain package separators, as in
C<$OUTER​::INNER​::var>. This implies nothing about the order of name
lookups, however. There are no relative packages​: all symbols are either
local to the current package, or must be fully qualified from the outer
package name down. For instance, there is nowhere within package C<OUTER>
that C<$INNER​::var> refers to C<$OUTER​::INNER​::var>. C<INNER> refers to a
totally separate global package. The custom of treating package names as a
hierachy is very strong, but the language in no way enforces it.

and the example in

The special symbol C<__PACKAGE__> contains the current package, but cannot
(easily) be used to construct variable names. After C<my($foo)> has hidden
package variable C<$foo>, it can still be accessed, without knowing what
package you are in, as C<${__PACKAGE__.'​::foo'}>.

On Fri, Dec 2, 2016 at 2​:47 PM, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

David, would you be able to submit a revised version of your Nov 23 patch that (a) is drawn against perl 5 blead; and (b) takes into account the discussion between you and Yves and others?

For myself​: +1 to eliminating the term "compilation unit"; +1 to eliminating mention of "magic variables".

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=129345

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @demerphq

++, waaay better than my attempt.

On 6 December 2016 at 05​:14, David Nicol <davidnicol@​gmail.com> wrote​:

commit a470df252293d4dc0aa3264022edf72e5a147d91
can be pulled from
https://github.com/davidnicol/perl

Here's my revised opening paragraph​:

Unlike Perl 4, in which all the variables were dynamic and shared one
global name space, causing maintainability problems, Perl 5 provides two
mechanisms for protecting code from having its variables stomped on by
other code​: lexical variables created with C<my>, C<our> or C<state> and
the C<package> declaration which instructs the compiler as to which
namespace to prefix to unqualified dynamic names, which both protects
against accidental stomping and provides an interface for deliberately
clobbering global dynamic variables declared and used in other scopes or
packages, when that is what you want to do. The scope of the package
declaration is from the declaration itself through the end of the
enclosing block, C<eval>, or file, whichever comes first (the same scope
as the my(), our(), state(), and local() operators, and also the effect
of the experimental "reference aliasing," which may change), or until
the next C<package> declaration. Unqualified dynamic identifiers will
be in this namespace, except for those few identifiers that, if
unqualified, default to the main package instead of the current one as
described below. A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, but I<not> lexical variables created with my(), our() or state().
Typically it is the first declaration in a file included by the C<do>,
C<require>, or C<use> operators. You can switch into a package in more
than one place​: C<package> has no effect beyond specifying which symbol
table the compiler will use for dynamic symbols for the rest of that
block or until the next C<package> statement. You can refer to
variables and filehandles in other packages by prefixing the identifier
with the package name and a double colon​: C<$Package​::Variable>. If the
package name is null, the C<main> package is assumed. That is,
C<$​::sail> is equivalent to C<$main​::sail>.

Also I added the last sentence in

Packages may themselves contain package separators, as in
C<$OUTER​::INNER​::var>. This implies nothing about the order of name
lookups, however. There are no relative packages​: all symbols are either
local to the current package, or must be fully qualified from the outer
package name down. For instance, there is nowhere within package C<OUTER>
that C<$INNER​::var> refers to C<$OUTER​::INNER​::var>. C<INNER> refers to a
totally separate global package. The custom of treating package names as a
hierachy is very strong, but the language in no way enforces it.

and the example in

The special symbol C<__PACKAGE__> contains the current package, but cannot
(easily) be used to construct variable names. After C<my($foo)> has hidden
package variable C<$foo>, it can still be accessed, without knowing what
package you are in, as C<${__PACKAGE__.'​::foo'}>.

On Fri, Dec 2, 2016 at 2​:47 PM, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

David, would you be able to submit a revised version of your Nov 23 patch that (a) is drawn against perl 5 blead; and (b) takes into account the discussion between you and Yves and others?

For myself​: +1 to eliminating the term "compilation unit"; +1 to eliminating mention of "magic variables".

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=129345

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

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

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @jkeenan

On Tue, 06 Dec 2016 08​:24​:27 GMT, demerphq wrote​:

++, waaay better than my attempt.

On 6 December 2016 at 05​:14, David Nicol <davidnicol@​gmail.com> wrote​:

commit a470df252293d4dc0aa3264022edf72e5a147d91
can be pulled from
https://github.com/davidnicol/perl

Here's my revised opening paragraph​:

Unlike Perl 4, in which all the variables were dynamic and shared one
global name space, causing maintainability problems, Perl 5 provides
two
mechanisms for protecting code from having its variables stomped on
by
other code​: lexical variables created with C<my>, C<our> or C<state>
and
the C<package> declaration which instructs the compiler as to which
namespace to prefix to unqualified dynamic names, which both protects
against accidental stomping and provides an interface for
deliberately
clobbering global dynamic variables declared and used in other scopes
or
packages, when that is what you want to do. The scope of the package
declaration is from the declaration itself through the end of the
enclosing block, C<eval>, or file, whichever comes first (the same
scope
as the my(), our(), state(), and local() operators, and also the
effect
of the experimental "reference aliasing," which may change), or until
the next C<package> declaration. Unqualified dynamic identifiers
will
be in this namespace, except for those few identifiers that, if
unqualified, default to the main package instead of the current one
as
described below. A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used
local()
on, but I<not> lexical variables created with my(), our() or state().
Typically it is the first declaration in a file included by the
C<do>,
C<require>, or C<use> operators. You can switch into a package in
more
than one place​: C<package> has no effect beyond specifying which
symbol
table the compiler will use for dynamic symbols for the rest of that
block or until the next C<package> statement. You can refer to
variables and filehandles in other packages by prefixing the
identifier
with the package name and a double colon​: C<$Package​::Variable>. If
the
package name is null, the C<main> package is assumed. That is,
C<$​::sail> is equivalent to C<$main​::sail>.

Also I added the last sentence in

Packages may themselves contain package separators, as in
C<$OUTER​::INNER​::var>. This implies nothing about the order of name
lookups, however. There are no relative packages​: all symbols are
either
local to the current package, or must be fully qualified from the
outer
package name down. For instance, there is nowhere within package
C<OUTER>
that C<$INNER​::var> refers to C<$OUTER​::INNER​::var>. C<INNER> refers
to a
totally separate global package. The custom of treating package names
as a
hierachy is very strong, but the language in no way enforces it.

and the example in

The special symbol C<__PACKAGE__> contains the current package, but
cannot
(easily) be used to construct variable names. After C<my($foo)> has
hidden
package variable C<$foo>, it can still be accessed, without knowing
what
package you are in, as C<${__PACKAGE__.'​::foo'}>.

On Fri, Dec 2, 2016 at 2​:47 PM, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

David, would you be able to submit a revised version of your Nov 23
patch that (a) is drawn against perl 5 blead; and (b) takes into
account the discussion between you and Yves and others?

For myself​: +1 to eliminating the term "compilation unit"; +1 to
eliminating mention of "magic variables".

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=129345

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

Applied to blead in commit e6dc2956963a07973f01d3be9657dbb146eba625 with one spelling correction and some line rebreaks to better match the existing file and thereby reduce the number of lines showing up in a diff.

The first paragraph is quite long and contains run-on sentences. In about a week -- after everyone has had a chance to digest the new language -- I'll come back and do some touch-ups for readability.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @jkeenan

On Tue, 06 Dec 2016 14​:05​:33 GMT, jkeenan wrote​:

Applied to blead in commit e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better match
the existing file and thereby reduce the number of lines showing up in
a diff.

Due to some 'git push' confusion on my part, I had to re-fetch and re-push. The actual commit is​:

commit c2e0820

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @davidnicol

Applied to blead in commit e6dc2956963a07973f01d3be9657dbb146eba625 with one spelling correction and some line rebreaks to better match the existing file and thereby reduce the number of lines showing up in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @jkeenan

On Tue, 06 Dec 2016 20​:29​:44 GMT, davidnicol@​gmail.com wrote​:

Applied to blead in commit e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better match
the existing file and thereby reduce the number of lines showing up
in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

What I did is definitely not something I normally do when applying a patch. But the first paragraph in the change set was so long and densely packed that vimdiff was pretty useless in examining the changes. I wanted to apply your changes but I also wanted to make certain nothing was overlooked. As previously stated, I want to allow a few days for any last-minute objections to the content. Then I'll go in, break this into > 1 paragraph, tidy it up and close the ticket.

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @demerphq

On 6 December 2016 at 21​:43, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 20​:29​:44 GMT, davidnicol@​gmail.com wrote​:

Applied to blead in commit e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better match
the existing file and thereby reduce the number of lines showing up
in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

What I did is definitely not something I normally do when applying a patch. But the first paragraph in the change set was so long and densely packed that vimdiff was pretty useless in examining the changes. I wanted to apply your changes but I also wanted to make certain nothing was overlooked. As previously stated, I want to allow a few days for any last-minute objections to the content. Then I'll go in, break this into > 1 paragraph, tidy it up and close the ticket.

Thank you very much.

I tweaked the language a bit with​:

commit 6bc3ceb
Author​: Yves Orton <demerphq@​gmail.com>
Date​: Tue Dec 6 22​:29​:03 2016 +0100

  tweak perlmod.pod

Inline Patch
diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 888b54b..2a101b6 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@@ -31,9 +31,15 @@ X<package> X<namespace> X<variable, global>
X X Unlike Perl 4\, in which all the variables were dynamic and shared one global name space\, causing maintainability problems\, Perl 5 provides two mechanisms for protecting code from having its variables stomped on by \-other code​: lexical variables created with C\\, C\ or C\ and \-the C\ declaration which instructs the compiler as to which \-namespace to prefix to unqualified dynamic names\, which both protects \+other code​: lexically scoped variables created with C\ or C\ and \+namespaced global variables\, which are exposed via the C\ pragma\, \+or the C\ keyword\. Any global variable is considered to \+be part of a namespace and can be accessed via a "fully qualified form"\, \+and conversly any lexically scoped variable is considered to be part of \+that lexical\-scope\, and does not have a "fully qualified form"\. \+In perl namespaces are called "packages" and \+the C\ declaration instructs the compiler as to which \+namespace to prefix to C\ variables and unqualified dynamic names\, which both protects against accidental stomping and provides an interface for deliberately clobbering global dynamic variables declared and used in other scopes or packages\, when that is what you want to do\.

I would really like to break this up into reasonable paragraphs and
edit it further.

It is very hard to follow as dense as it is.

Would you object James?

Yves

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @jkeenan

On Tue, 06 Dec 2016 21​:33​:43 GMT, demerphq wrote​:

On 6 December 2016 at 21​:43, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 20​:29​:44 GMT, davidnicol@​gmail.com wrote​:

Applied to blead in commit
e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better
match
the existing file and thereby reduce the number of lines showing
up
in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

What I did is definitely not something I normally do when applying a
patch. But the first paragraph in the change set was so long and
densely packed that vimdiff was pretty useless in examining the
changes. I wanted to apply your changes but I also wanted to make
certain nothing was overlooked. As previously stated, I want to
allow a few days for any last-minute objections to the content. Then
I'll go in, break this into > 1 paragraph, tidy it up and close the
ticket.

Thank you very much.

I tweaked the language a bit with​:

commit 6bc3ceb
Author​: Yves Orton <demerphq@​gmail.com>
Date​: Tue Dec 6 22​:29​:03 2016 +0100

tweak perlmod.pod

diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 888b54b..2a101b6 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@​@​ -31,9 +31,15 @​@​ X<package> X<namespace> X<variable, global>
X<global variable> X<global>
Unlike Perl 4, in which all the variables were dynamic and shared one
global name space, causing maintainability problems, Perl 5 provides
two
mechanisms for protecting code from having its variables stomped on
by
-other code​: lexical variables created with C<my>, C<our> or C<state>
and
-the C<package> declaration which instructs the compiler as to which
-namespace to prefix to unqualified dynamic names, which both protects
+other code​: lexically scoped variables created with C<my> or C<state>
and
+namespaced global variables, which are exposed via the C<vars>
pragma,
+or the C<our> keyword. Any global variable is considered to
+be part of a namespace and can be accessed via a "fully qualified
form",
+and conversly any lexically scoped variable is considered to be part

s/conversly/conversely/

of
+that lexical-scope, and does not have a "fully qualified form".
+In perl namespaces are called "packages" and
+the C<package> declaration instructs the compiler as to which
+namespace to prefix to C<our> variables and unqualified dynamic
names, which both protects
against accidental stomping and provides an interface for
deliberately
clobbering global dynamic variables declared and used in other scopes
or
packages, when that is what you want to do.

I would really like to break this up into reasonable paragraphs and
edit it further.

It is very hard to follow as dense as it is.

Agreed.

Would you object James?

Well, as previously stated, I planned to do that after the all the dust as to the content had settled. For example, the sentence starting with "In perl namespaces ..." really needs to be trimmed. I'd like to pause on the copy-editing for two days so that if anyone (in addition to you) has real content objections/suggestions, we can settle on those first.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @demerphq

On 6 December 2016 at 23​:36, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 21​:33​:43 GMT, demerphq wrote​:

On 6 December 2016 at 21​:43, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 20​:29​:44 GMT, davidnicol@​gmail.com wrote​:

Applied to blead in commit
e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better
match
the existing file and thereby reduce the number of lines showing
up
in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

What I did is definitely not something I normally do when applying a
patch. But the first paragraph in the change set was so long and
densely packed that vimdiff was pretty useless in examining the
changes. I wanted to apply your changes but I also wanted to make
certain nothing was overlooked. As previously stated, I want to
allow a few days for any last-minute objections to the content. Then
I'll go in, break this into > 1 paragraph, tidy it up and close the
ticket.

Thank you very much.

I tweaked the language a bit with​:

commit 6bc3ceb
Author​: Yves Orton <demerphq@​gmail.com>
Date​: Tue Dec 6 22​:29​:03 2016 +0100

tweak perlmod.pod

diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 888b54b..2a101b6 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@​@​ -31,9 +31,15 @​@​ X<package> X<namespace> X<variable, global>
X<global variable> X<global>
Unlike Perl 4, in which all the variables were dynamic and shared one
global name space, causing maintainability problems, Perl 5 provides
two
mechanisms for protecting code from having its variables stomped on
by
-other code​: lexical variables created with C<my>, C<our> or C<state>
and
-the C<package> declaration which instructs the compiler as to which
-namespace to prefix to unqualified dynamic names, which both protects
+other code​: lexically scoped variables created with C<my> or C<state>
and
+namespaced global variables, which are exposed via the C<vars>
pragma,
+or the C<our> keyword. Any global variable is considered to
+be part of a namespace and can be accessed via a "fully qualified
form",
+and conversly any lexically scoped variable is considered to be part

s/conversly/conversely/

Ill push a fix. Sorry.

of
+that lexical-scope, and does not have a "fully qualified form".
+In perl namespaces are called "packages" and
+the C<package> declaration instructs the compiler as to which
+namespace to prefix to C<our> variables and unqualified dynamic
names, which both protects
against accidental stomping and provides an interface for
deliberately
clobbering global dynamic variables declared and used in other scopes
or
packages, when that is what you want to do.

I would really like to break this up into reasonable paragraphs and
edit it further.

It is very hard to follow as dense as it is.

Agreed.

Would you object James?

Well, as previously stated, I planned to do that after the all the dust as to the content had settled. For example, the sentence starting with "In perl namespaces ..." really needs to be trimmed. I'd like to pause on the copy-editing for two days so that if anyone (in addition to you) has real content objections/suggestions, we can settle on those first.

Sure. For the record, my main objection which lead to my change is
that our() doesn't create a lexical in the same way that my() does.
Personally i doubt i can contribute much on content until it is made
more readable. I had to fight the urge to continue editing. :-)

cheers,
Yves

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

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 2016

From @davidnicol

On Tue, Dec 6, 2016 at 5​:11 PM, demerphq <demerphq@​gmail.com> wrote​:

Sure. For the record, my main objection which lead to my change is
that our() doesn't create a lexical in the same way that my() does.
Personally i doubt i can contribute much on content until it is made
more readable. I had to fight the urge to continue editing. :-)

cheers,
Yves

Me too. Has "use strict" become the default yet? Are we still trying
to move in that direction?

Inline Patch
diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 2a101b6..01656ec 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@@ -32,14 +32,18 @@ Unlike Perl 4, in which all the variables were
dynamic and shared one global name space\, causing maintainability problems\, Perl 5 provides two mechanisms for protecting code from having its variables stomped on by other code​: lexically scoped variables created with C\ or C\ and \-namespaced global variables\, which are exposed via the C\ pragma\, \-or the C\ keyword\. Any global variable is considered to \+namespaced global variables\, which autovivify into the current namespace\, \+or can be declared \(when in "strict" mode\) via the C\ pragma\, \+or the C\ keyword\, which aliases a "my" variable to a package variable\. \+Any global variable is considered to be part of a namespace and can be accessed via a "fully qualified form"\, and conversly any lexically scoped variable is considered to be part of that lexical\-scope\, and does not have a "fully qualified form"\. \+ In perl namespaces are called "packages" and the C\ declaration instructs the compiler as to which \-namespace to prefix to C\ variables and unqualified dynamic names\, which both protects \+namespace to prefix to autovivified and C\ variables\, and unqualified dynamic names\, \+which both protects against accidental stomping and provides an interface for deliberately clobbering global dynamic variables declared and used in other scopes or packages\, when that is what you want to do\. @​@​ \-53\,7 \+57\,7 @​@​ this namespace\, except for those few identifiers that\, if unqualified\, default to the main package instead of the current one as described below\. A package statement affects only dynamic global symbols\, including subroutine names\, and variables you've used local\(\) \-on\, but I\ lexical variables created with my\(\)\, our\(\) or state\(\)\. \+on\, but I\ the lexical variables created with my\(\)\, our\(\) or state\(\)\. Typically it is the first declaration in a file included by the C\\, C\\, or C\ operators\. You can switch into a package in more than one place​: C\ has no @​@​ \-63\,7 \+67\,10 @​@​ You can refer to variables and filehandles in other packages by prefixing the identifier with the package name and a double colon​: C\<$Package​::Variable>\. If the package name is null\, the C\ package is assumed\. That is\, C\<$​::sail> is equivalent to \-C\<$main​::sail>\. \+C\<$main​::sail>\. In case it isn't entirely clear\, when talking about Perl's names \+for variables and subroutines\, "package\," "global\," and "dynamic" mean the same thing \+and are effectively interchangable\, opposed to "lexical" which means visible only after the \+declaration in the current scope and other scopes inner to it\, like "var" variables in Javascript\.

The old package delimiter was a single quote, but double colon is now the
preferred delimiter, in part because it's more readable to humans, and

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 2016

From @Abigail

On Mon, Dec 05, 2016 at 10​:14​:24PM -0600, David Nicol wrote​:

commit a470df252293d4dc0aa3264022edf72e5a147d91
can be pulled from
https://github.com/davidnicol/perl

Here's my revised opening paragraph​:

Unlike Perl 4, in which all the variables were dynamic and shared one
global name space, causing maintainability problems, Perl 5 provides two
mechanisms for protecting code from having its variables stomped on by
other code​: lexical variables created with C<my>, C<our> or C<state> and
the C<package> declaration which instructs the compiler as to which
namespace to prefix to unqualified dynamic names, which both protects
against accidental stomping and provides an interface for deliberately
clobbering global dynamic variables declared and used in other scopes or
packages, when that is what you want to do.

That's a 600+ character opening sentence; I find it pretty hard to
read, and impossible to figure out whether the author wants to inform
me about Perl 5 syntax, Perl 5 implementation, wants to rant about
Perl 4 scoping, or wants to give programming advice. Let's not forget
not every user of Perl is native English speaker.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 2016

From @davidnicol

How's this?

In Perl 4 all the symbols (variables and subroutine names) were
dynamic and shared one global name space, causing maintainability
problems. Perl 5 initially provided two mechanisms for protecting code
from having its variables stomped on by other code​: lexically scoped
variables created with C<my> and namespaces for the dynamic global
symbols. The operator that declares which namespace unqualified
symbols not found in the scope's lexical table are to be found in or
autovivified into is C<package>. Later additional mechanisms were
provided​: the C<our> keyword, which aliases a "my" variable to a
package variable, and the C<state> keyword, which creates a my()
variable that does not get reset, as an alternative to the useful but
confusing idiom found in some older Perl 5 code, C<my $foo if 0;>. Any
global variable is considered to be part of a namespace and can be
accessed via a "fully qualified form", and conversely any lexically
scoped variable is considered to be part of its lexical scope, and
does not have a "fully qualified form".

Also, as a non-native speaker of English, do you recognize any
semantic weight whatsoever to the "the" in

A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, but I<not> the lexical variables created with my(), our() or state().

opposed to

A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, but I<not> lexical variables created with my(), our() or state().

This "the" controversy might be a new low point in bikeshedding the
documentation and I am having trouble articulating why I proposed
adding the new "the." The sentence could get stripped further instead

A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, I<not> lexical variables created with my(), our() or state().

or just removed entirely, as what it says has been stated previously.

**** new thought ****

"package" "global" and "dynamic" are used interchangably, but should
the documentation say something about the differentiating nuances?
After pondering that question a bit I have come up with these
differentiators​:

* One says "package variable" when emphasizing how a symbol is
convenient to a package, as within the package it does not need to be
qualified with its namespace

* One says "global variable" when emphasizing how package variables
can be accessed from other namespaces using their fully qualified
forms

* One says "dynamic variable" when emphasizing how the symbol tables
are run-time data structures instead of temporary abstractions used
only during compilation, and autovivification. Perl 6 has something
else it calls a "dynamic variable" which does not exist in Perl 5.

On Wed, Dec 7, 2016 at 7​:42 AM, Abigail <abigail@​abigail.be> wrote​:

On Mon, Dec 05, 2016 at 10​:14​:24PM -0600, David Nicol wrote​:

commit a470df252293d4dc0aa3264022edf72e5a147d91
can be pulled from
https://github.com/davidnicol/perl

Here's my revised opening paragraph​:

Unlike Perl 4, in which all the variables were dynamic and shared one
global name space, causing maintainability problems, Perl 5 provides two
mechanisms for protecting code from having its variables stomped on by
other code​: lexical variables created with C<my>, C<our> or C<state> and
the C<package> declaration which instructs the compiler as to which
namespace to prefix to unqualified dynamic names, which both protects
against accidental stomping and provides an interface for deliberately
clobbering global dynamic variables declared and used in other scopes or
packages, when that is what you want to do.

That's a 600+ character opening sentence; I find it pretty hard to
read, and impossible to figure out whether the author wants to inform
me about Perl 5 syntax, Perl 5 implementation, wants to rant about
Perl 4 scoping, or wants to give programming advice. Let's not forget
not every user of Perl is native English speaker.

Abigail

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 2016

From @demerphq

On 7 December 2016 at 16​:48, David Nicol <davidnicol@​gmail.com> wrote​:

How's this?

In Perl 4 all the symbols (variables and subroutine names) were
dynamic and shared one global name space, causing maintainability
problems. Perl 5 initially provided two mechanisms for protecting code
from having its variables stomped on by other code​: lexically scoped
variables created with C<my> and namespaces for the dynamic global
symbols. The operator that declares which namespace unqualified
symbols not found in the scope's lexical table are to be found in or
autovivified into is C<package>. Later additional mechanisms were
provided​: the C<our> keyword, which aliases a "my" variable to a
package variable, and the C<state> keyword, which creates a my()
variable that does not get reset, as an alternative to the useful but
confusing idiom found in some older Perl 5 code, C<my $foo if 0;>. Any
global variable is considered to be part of a namespace and can be
accessed via a "fully qualified form", and conversely any lexically
scoped variable is considered to be part of its lexical scope, and
does not have a "fully qualified form".

Also, as a non-native speaker of English, do you recognize any
semantic weight whatsoever to the "the" in

A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, but I<not> the lexical variables created with my(), our() or state().

opposed to

A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, but I<not> lexical variables created with my(), our() or state().

This "the" controversy might be a new low point in bikeshedding the
documentation and I am having trouble articulating why I proposed
adding the new "the." The sentence could get stripped further instead

A package statement affects only dynamic global
symbols, including subroutine names, and variables you've used local()
on, I<not> lexical variables created with my(), our() or state().

or just removed entirely, as what it says has been stated previously.

**** new thought ****

"package" "global" and "dynamic" are used interchangably, but should
the documentation say something about the differentiating nuances?
After pondering that question a bit I have come up with these
differentiators​:

* One says "package variable" when emphasizing how a symbol is
convenient to a package, as within the package it does not need to be
qualified with its namespace

* One says "global variable" when emphasizing how package variables
can be accessed from other namespaces using their fully qualified
forms

* One says "dynamic variable" when emphasizing how the symbol tables
are run-time data structures instead of temporary abstractions used
only during compilation, and autovivification. Perl 6 has something
else it calls a "dynamic variable" which does not exist in Perl 5.

Personally, I consider global variable and package variable to be the
same thing.

I consider "dynamic variable" to be a broken-term which conflates
"dynamic scoping" and "global variables", probably because all global
vars can have dynamic scoping effects.

However, any composite member of a lexically scoped variable may be
dynamically scoped, so the term "dynamic variable" is meaningless.

consider​:

my %hash=(foo=>1);
{
  local $hash{foo}= "bar";
  print $hash{foo},"\n";
}
print $hash{foo},"\n";

I think the term "dynamic" should apply only to scoping, especially
with regard to the use of local, and not to variable names.

Again, I think the use of dynamic variable is because you can localize
global $foo, but you cant localize a lexical $foo (but you can
localize $foo{bar} regardles if %foo is global or lexical).

Yves

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

@p5pRT
Copy link
Author

p5pRT commented Dec 11, 2016

From @jkeenan

On Tue, 06 Dec 2016 23​:11​:46 GMT, demerphq wrote​:

On 6 December 2016 at 23​:36, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 21​:33​:43 GMT, demerphq wrote​:

On 6 December 2016 at 21​:43, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 20​:29​:44 GMT, davidnicol@​gmail.com wrote​:

Applied to blead in commit
e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better
match
the existing file and thereby reduce the number of lines
showing
up
in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and
just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

What I did is definitely not something I normally do when applying
a
patch. But the first paragraph in the change set was so long and
densely packed that vimdiff was pretty useless in examining the
changes. I wanted to apply your changes but I also wanted to make
certain nothing was overlooked. As previously stated, I want to
allow a few days for any last-minute objections to the content.
Then
I'll go in, break this into > 1 paragraph, tidy it up and close
the
ticket.

Thank you very much.

I tweaked the language a bit with​:

commit 6bc3ceb
Author​: Yves Orton <demerphq@​gmail.com>
Date​: Tue Dec 6 22​:29​:03 2016 +0100

tweak perlmod.pod

diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 888b54b..2a101b6 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@​@​ -31,9 +31,15 @​@​ X<package> X<namespace> X<variable, global>
X<global variable> X<global>
Unlike Perl 4, in which all the variables were dynamic and shared
one
global name space, causing maintainability problems, Perl 5
provides
two
mechanisms for protecting code from having its variables stomped on
by
-other code​: lexical variables created with C<my>, C<our> or
C<state>
and
-the C<package> declaration which instructs the compiler as to which
-namespace to prefix to unqualified dynamic names, which both
protects
+other code​: lexically scoped variables created with C<my> or
C<state>
and
+namespaced global variables, which are exposed via the C<vars>
pragma,
+or the C<our> keyword. Any global variable is considered to
+be part of a namespace and can be accessed via a "fully qualified
form",
+and conversly any lexically scoped variable is considered to be
part

s/conversly/conversely/

Ill push a fix. Sorry.

of
+that lexical-scope, and does not have a "fully qualified form".
+In perl namespaces are called "packages" and
+the C<package> declaration instructs the compiler as to which
+namespace to prefix to C<our> variables and unqualified dynamic
names, which both protects
against accidental stomping and provides an interface for
deliberately
clobbering global dynamic variables declared and used in other
scopes
or
packages, when that is what you want to do.

I would really like to break this up into reasonable paragraphs and
edit it further.

It is very hard to follow as dense as it is.

Agreed.

Would you object James?

Well, as previously stated, I planned to do that after the all the
dust as to the content had settled. For example, the sentence
starting with "In perl namespaces ..." really needs to be trimmed.
I'd like to pause on the copy-editing for two days so that if anyone
(in addition to you) has real content objections/suggestions, we can
settle on those first.

Sure. For the record, my main objection which lead to my change is
that our() doesn't create a lexical in the same way that my() does.
Personally i doubt i can contribute much on content until it is made
more readable. I had to fight the urge to continue editing. :-)

cheers,
Yves

In commit 0ee4a8b I have corrected the typo and made some revisions aimed solely at improvements in readability, e.g., breaking one long paragraph into four.

The content discussion can continue.

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Feb 7, 2017

From @khwilliamson

On Sun, 11 Dec 2016 05​:46​:52 -0800, jkeenan wrote​:

On Tue, 06 Dec 2016 23​:11​:46 GMT, demerphq wrote​:

On 6 December 2016 at 23​:36, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 21​:33​:43 GMT, demerphq wrote​:

On 6 December 2016 at 21​:43, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 20​:29​:44 GMT, davidnicol@​gmail.com wrote​:

Applied to blead in commit
e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better
match
the existing file and thereby reduce the number of lines
showing
up
in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and
just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

What I did is definitely not something I normally do when
applying
a
patch. But the first paragraph in the change set was so long
and
densely packed that vimdiff was pretty useless in examining the
changes. I wanted to apply your changes but I also wanted to
make
certain nothing was overlooked. As previously stated, I want to
allow a few days for any last-minute objections to the content.
Then
I'll go in, break this into > 1 paragraph, tidy it up and close
the
ticket.

Thank you very much.

I tweaked the language a bit with​:

commit 6bc3ceb
Author​: Yves Orton <demerphq@​gmail.com>
Date​: Tue Dec 6 22​:29​:03 2016 +0100

tweak perlmod.pod

diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 888b54b..2a101b6 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@​@​ -31,9 +31,15 @​@​ X<package> X<namespace> X<variable, global>
X<global variable> X<global>
Unlike Perl 4, in which all the variables were dynamic and shared
one
global name space, causing maintainability problems, Perl 5
provides
two
mechanisms for protecting code from having its variables stomped
on
by
-other code​: lexical variables created with C<my>, C<our> or
C<state>
and
-the C<package> declaration which instructs the compiler as to
which
-namespace to prefix to unqualified dynamic names, which both
protects
+other code​: lexically scoped variables created with C<my> or
C<state>
and
+namespaced global variables, which are exposed via the C<vars>
pragma,
+or the C<our> keyword. Any global variable is considered to
+be part of a namespace and can be accessed via a "fully qualified
form",
+and conversly any lexically scoped variable is considered to be
part

s/conversly/conversely/

Ill push a fix. Sorry.

of
+that lexical-scope, and does not have a "fully qualified form".
+In perl namespaces are called "packages" and
+the C<package> declaration instructs the compiler as to which
+namespace to prefix to C<our> variables and unqualified dynamic
names, which both protects
against accidental stomping and provides an interface for
deliberately
clobbering global dynamic variables declared and used in other
scopes
or
packages, when that is what you want to do.

I would really like to break this up into reasonable paragraphs
and
edit it further.

It is very hard to follow as dense as it is.

Agreed.

Would you object James?

Well, as previously stated, I planned to do that after the all the
dust as to the content had settled. For example, the sentence
starting with "In perl namespaces ..." really needs to be trimmed.
I'd like to pause on the copy-editing for two days so that if
anyone
(in addition to you) has real content objections/suggestions, we
can
settle on those first.

Sure. For the record, my main objection which lead to my change is
that our() doesn't create a lexical in the same way that my() does.
Personally i doubt i can contribute much on content until it is made
more readable. I had to fight the urge to continue editing. :-)

cheers,
Yves

In commit 0ee4a8b I have corrected
the typo and made some revisions aimed solely at improvements in
readability, e.g., breaking one long paragraph into four.

The content discussion can continue.

Thank you very much.

There has been no further discussion. Can this ticket be closed?
--
Karl Williamson

@p5pRT
Copy link
Author

p5pRT commented Feb 8, 2017

From @jkeenan

On 02/07/2017 05​:46 PM, Karl Williamson via RT wrote​:

On Sun, 11 Dec 2016 05​:46​:52 -0800, jkeenan wrote​:

On Tue, 06 Dec 2016 23​:11​:46 GMT, demerphq wrote​:

On 6 December 2016 at 23​:36, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 21​:33​:43 GMT, demerphq wrote​:

On 6 December 2016 at 21​:43, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Tue, 06 Dec 2016 20​:29​:44 GMT, davidnicol@​gmail.com wrote​:

Applied to blead in commit
e6dc2956963a07973f01d3be9657dbb146eba625
with one spelling correction and some line rebreaks to better
match
the existing file and thereby reduce the number of lines
showing
up
in a diff.
--
James E Keenan (jkeenan@​cpan.org)

I gave up on optimizing for diff length within a paragraph, and
just
ran my revisions through "|fmt -w 73" which might become a best
practice, if it catches on. Thoughts?

What I did is definitely not something I normally do when
applying
a
patch. But the first paragraph in the change set was so long
and
densely packed that vimdiff was pretty useless in examining the
changes. I wanted to apply your changes but I also wanted to
make
certain nothing was overlooked. As previously stated, I want to
allow a few days for any last-minute objections to the content.
Then
I'll go in, break this into > 1 paragraph, tidy it up and close
the
ticket.

Thank you very much.

I tweaked the language a bit with​:

commit 6bc3ceb
Author​: Yves Orton <demerphq@​gmail.com>
Date​: Tue Dec 6 22​:29​:03 2016 +0100

tweak perlmod.pod

diff --git a/pod/perlmod.pod b/pod/perlmod.pod
index 888b54b..2a101b6 100644
--- a/pod/perlmod.pod
+++ b/pod/perlmod.pod
@​@​ -31,9 +31,15 @​@​ X<package> X<namespace> X<variable, global>
X<global variable> X<global>
Unlike Perl 4, in which all the variables were dynamic and shared
one
global name space, causing maintainability problems, Perl 5
provides
two
mechanisms for protecting code from having its variables stomped
on
by
-other code​: lexical variables created with C<my>, C<our> or
C<state>
and
-the C<package> declaration which instructs the compiler as to
which
-namespace to prefix to unqualified dynamic names, which both
protects
+other code​: lexically scoped variables created with C<my> or
C<state>
and
+namespaced global variables, which are exposed via the C<vars>
pragma,
+or the C<our> keyword. Any global variable is considered to
+be part of a namespace and can be accessed via a "fully qualified
form",
+and conversly any lexically scoped variable is considered to be
part

s/conversly/conversely/

Ill push a fix. Sorry.

of
+that lexical-scope, and does not have a "fully qualified form".
+In perl namespaces are called "packages" and
+the C<package> declaration instructs the compiler as to which
+namespace to prefix to C<our> variables and unqualified dynamic
names, which both protects
against accidental stomping and provides an interface for
deliberately
clobbering global dynamic variables declared and used in other
scopes
or
packages, when that is what you want to do.

I would really like to break this up into reasonable paragraphs
and
edit it further.

It is very hard to follow as dense as it is.

Agreed.

Would you object James?

Well, as previously stated, I planned to do that after the all the
dust as to the content had settled. For example, the sentence
starting with "In perl namespaces ..." really needs to be trimmed.
I'd like to pause on the copy-editing for two days so that if
anyone
(in addition to you) has real content objections/suggestions, we
can
settle on those first.

Sure. For the record, my main objection which lead to my change is
that our() doesn't create a lexical in the same way that my() does.
Personally i doubt i can contribute much on content until it is made
more readable. I had to fight the urge to continue editing. :-)

cheers,
Yves

In commit 0ee4a8b I have corrected
the typo and made some revisions aimed solely at improvements in
readability, e.g., breaking one long paragraph into four.

The content discussion can continue.

Thank you very much.

There has been no further discussion. Can this ticket be closed?

Yes, let's put new discussion, if any, in a new ticket.

Thank you very much.
jimk

@p5pRT
Copy link
Author

p5pRT commented Feb 8, 2017

From @khwilliamson

Now closed
--
Karl Williamson

@p5pRT
Copy link
Author

p5pRT commented Feb 8, 2017

@khwilliamson - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release today of Perl 5.26.0, this and 210 other issues have been
resolved.

Perl 5.26.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.26.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

@khwilliamson - Status changed from 'pending release' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant