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
Comments
From andy.glew@comp-arch.netCreated by andy@glew.netSee http://perldoc.perl.org/perlmod.html The package statement declares the compilation unit as being in the 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 (unless you guys want to take spercial pleading, and say that in the same package Foo; package Bar; 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
|
From zefram@fysh.orgvia RT wrote:
It doesn't: the next package statement produces a nested package scope.
Nested again. You have a package scope inside a my scope inside a -zefram |
The RT System itself - Status changed from 'new' to 'open' |
From @davidnicolthanks for this explanation! I too thought package replaced rather $ perl -le 'package a; { print __PACKAGE__; package b; print 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 dln On Sat, Sep 24, 2016 at 4:56 PM, Zefram <zefram@fysh.org> wrote:
-- |
From @jkeenanOn Sun, 25 Sep 2016 01:22:39 GMT, davidnicol@gmail.com wrote:
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. -- |
From @jkeenan129345-0001-Explain-complications-of-multiple-packages-within-a-.patchFrom 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
|
From @iabynOn Fri, Nov 18, 2016 at 04:34:16PM -0800, James E Keenan via RT wrote:
I think that contains far to much detail and will just tend to confuse -- |
From @jkeenanOn Mon, 21 Nov 2016 09:51:08 GMT, davem wrote:
Which I can understand. List: other opinions? -- |
From zefram@fysh.orgDave Mitchell wrote:
I concur. The critical part of the documentation is The scope of the package declaration is from the declaration itself which is perfectly explicit and clear. -zefram |
From @davidnicolOn Tue, Nov 22, 2016 at 11:20 PM, Zefram <zefram@fysh.org> wrote:
Saying "package" has the same scope as "my" can be read as implying package a; @apples = qw/gala fuji/ ; { package b; print "@apples" } should print "galafuji." Perl provides a mechanism for alternative namespaces to protect packages Also, what's up with this "In fact, there's really no such thing as a I submit this rewrite: Perl provides a mechanism for alternative namespaces to protect packages patch attached. -- |
From @davidnicolInline 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 |
From zefram@fysh.orgDavid Nicol wrote:
They are. The scopes are nested.
No. The closest enclosing scope takes precedence, as usual. This is no -zefram |
From @davidnicolyes, of course, that's how it works, and it looks to me like you can't The fact that there is exactly one active default namespace at any The packages active in the outer block are *not* active in the inner By changing The package statement declares the compilation unit as being in to The package statement instructs the compiler as to which namespace I hope to make it clear that there is exactly one namespace (singular) "being in the given namespace" doesn't make it clear that there is Do any twenty-somethings still learn Perl, anyway? On Wed, Nov 23, 2016 at 12:58 AM, Zefram <zefram@fysh.org> wrote:
-- |
From zefram@fysh.orgDavid Nicol wrote:
OK, that's a clarification worth making. -zefram |
From andy.glew@comp-arch.netFair enough - package and my (and probably other, like our, etc.) start new 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>
|
From andy.glew@comp-arch.netAll of my last message boils down to "In Perl, packages do not nest in terms of structure. But package scopes The content of this message is my personal opinion only. Although I am an On Wed, Nov 23, 2016 at 11:15 AM, <andy.glew@comp-arch.net> wrote:
|
From andy.glew@comp-arch.net@Zefram: I am fine on what you say about "The [package] scopes are nested. This makes sense. I am tempted to say "Where do the manuals say this?" But that is pushing I do point out that those of us who run with 'use warnings' are used to % perl -e 'use warnings; my $a=1; my $a=2; print $a;' so the behavior of package is not exactly the same as lexical variables of (No, I am not suggesting that 'package A; package A', i.e. two successive I think that my main confusion was thinking that "nested package scopes" I say "supposedly nested" because ... is there any way that you can tell (Where the hypothetical 'end_package' does not affect my variable scopes - I don't think there is such a way to distinguish such nesting. Which is The content of this message is my personal opinion only. Although I am an On Tue, Nov 22, 2016 at 10:58 PM, Zefram via RT <perlbug-followup@perl.org>
|
From @demerphqOn 23 November 2016 at 21:25, David Nicol <davidnicol@gmail.com> wrote:
I think so.
I would not say so. I would say compilation unit is something akin to
Because compilation unit includes the statement. I think the documentation should say something like "the package statement determines the namespace for unqualified global that is, it should make it clear that it is lexically scoped, and it Also, I would avoid the term dynamic variables in favour of the term
I disagree. While I am fine with you rewording it, I think the use of Some of your other criticisms are more compelling. "compilation unit" I wonder if we should use the term "namespace" at all or if we do if I guess some of the problem here comes from the fact that the package Yves |
From @davidnicolOn Thu, Nov 24, 2016 at 4:12 AM, demerphq <demerphq@gmail.com> wrote:
We (you and I) appear to be in agreement in favor of concerning
Works for me
Have you any explanation of where the "in fact, Perl has no such thing
Wouldn't make it clear to my hypothetical thick-skulled person who
how about "prefix" ?
There you go again with the global variables. In fact there is no such
dln -- |
From @demerphqOn 24 November 2016 at 18:20, David Nicol <davidnicol@gmail.com> wrote:
I definitely think documentation that explains what is going on
It was introduced in 5.001. So soon after the introduction of commit 748a930 Perl 5.001 [See the Changes file for a list of changes] Inline Patchdiff --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
Perl provides a mechanism for alternative namespaces to protect reads (to me) slightly differently. The original sentence reads "In fact, apart from certain magical variables, there's really no such which to me, combined with the context established by the preceding 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), Regardless the entire opening paragraph of perlmod reads to me like it
I am fine with rewording it, I just wanted to be clear I think that it
Yeah, I thought of that, but it doesn't do it for me.
:-) Lets get rid of that language. :-) cheers, -- |
From @jkeenanDavid, 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. |
From @davidnicolcommit a470df252293d4dc0aa3264022edf72e5a147d91 Here's my revised opening paragraph: Unlike Perl 4, in which all the variables were dynamic and shared one Also I added the last sentence in Packages may themselves contain package separators, as in and the example in The special symbol C<__PACKAGE__> contains the current package, but cannot On Fri, Dec 2, 2016 at 2:47 PM, James E Keenan via RT
-- |
From @demerphq++, waaay better than my attempt. On 6 December 2016 at 05:14, David Nicol <davidnicol@gmail.com> wrote:
-- |
From @jkeenanOn Tue, 06 Dec 2016 08:24:27 GMT, demerphq 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. 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. -- |
From @jkeenanOn Tue, 06 Dec 2016 14:05:33 GMT, jkeenan wrote:
Due to some 'git push' confusion on my part, I had to re-fetch and re-push. The actual commit is: commit c2e0820 -- |
From @davidnicol
I gave up on optimizing for diff length within a paragraph, and just -- |
From @jkeenanOn Tue, 06 Dec 2016 20:29:44 GMT, davidnicol@gmail.com wrote:
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. |
From @demerphqOn 6 December 2016 at 21:43, James E Keenan via RT
I tweaked the language a bit with: commit 6bc3ceb tweak perlmod.pod Inline Patchdiff --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>
I would really like to break this up into reasonable paragraphs and It is very hard to follow as dense as it is. Would you object James? Yves |
From @jkeenanOn Tue, 06 Dec 2016 21:33:43 GMT, demerphq wrote:
s/conversly/conversely/
Agreed.
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. -- |
From @demerphqOn 6 December 2016 at 23:36, James E Keenan via RT
Ill push a fix. Sorry.
Sure. For the record, my main objection which lead to my change is cheers, -- |
From @davidnicolOn Tue, Dec 6, 2016 at 5:11 PM, demerphq <demerphq@gmail.com> wrote:
Me too. Has "use strict" become the default yet? Are we still trying Inline Patchdiff --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
The old package delimiter was a single quote, but double colon is now the -- |
From @AbigailOn Mon, Dec 05, 2016 at 10:14:24PM -0600, David Nicol wrote:
That's a 600+ character opening sentence; I find it pretty hard to Abigail |
From @davidnicolHow's this? In Perl 4 all the symbols (variables and subroutine names) were Also, as a non-native speaker of English, do you recognize any A package statement affects only dynamic global opposed to A package statement affects only dynamic global This "the" controversy might be a new low point in bikeshedding the A package statement affects only dynamic global or just removed entirely, as what it says has been stated previously. **** new thought **** "package" "global" and "dynamic" are used interchangably, but should * One says "package variable" when emphasizing how a symbol is * One says "global variable" when emphasizing how package variables * One says "dynamic variable" when emphasizing how the symbol tables On Wed, Dec 7, 2016 at 7:42 AM, Abigail <abigail@abigail.be> wrote:
-- |
From @demerphqOn 7 December 2016 at 16:48, David Nicol <davidnicol@gmail.com> wrote:
Personally, I consider global variable and package variable to be the I consider "dynamic variable" to be a broken-term which conflates However, any composite member of a lexically scoped variable may be consider: my %hash=(foo=>1); I think the term "dynamic" should apply only to scoping, especially Again, I think the use of dynamic variable is because you can localize Yves -- |
From @jkeenanOn Tue, 06 Dec 2016 23:11:46 GMT, demerphq wrote:
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. |
From @khwilliamsonOn Sun, 11 Dec 2016 05:46:52 -0800, jkeenan wrote:
There has been no further discussion. Can this ticket be closed? |
From @jkeenanOn 02/07/2017 05:46 PM, Karl Williamson via RT wrote:
Yes, let's put new discussion, if any, in a new ticket. Thank you very much. |
From @khwilliamsonNow closed |
@khwilliamson - Status changed from 'open' to 'pending release' |
From @khwilliamsonThank 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 Perl 5.26.0 may be downloaded via: If you find that the problem persists, feel free to reopen this ticket. |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
Migrated from rt.perl.org#129345 (status was 'resolved')
Searchable as RT129345$
The text was updated successfully, but these errors were encountered: