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
[BUG our() 5.005_63] Lexical scoping problems. #1071
Comments
From @schwernour $a = "Outer"; $a is "Inner" in both places. If I understand how our() works, its Next, our() doesn't appear to localize in a loop conditional: our $a = "Outer"; $a is 3, not "Outer" after the for loop. I presume the two bugs are However, this -does- work as expected. our $a = "Outer"; $a is 'Outer' after the for loop. Summary of my perl5 (revision 5.0 version 5 subversion 63) configuration: Characteristics of this binary (from libperl): -- Michael G Schwern schwern@pobox.com |
From @gsarOn Mon, 24 Jan 2000 00:01:21 EST, Michael G Schwern wrote:
Of course it is; both $a's are aliases to the same global. our doesn't I think the "our" variable masks ... warning had better be extended Sarathy |
From @schwernOn Sun, Jan 23, 2000 at 09:38:42PM -0800, Gurusamy Sarathy wrote:
Oh, then the docs in perlfunc are a little confusing. I read: An our declares the listed variables to be valid as basically, "it scopes just like a my() variable except you can Okay, so color me stupid, but why is our()'s lexical scoping PS I just realized I've been using $a in my examples and tests, I -- Michael G Schwern schwern@pobox.com |
From [Unknown Contact. See original ticket]Michael G Schwern wrote:
I can't see any situation where this is actually /necessary/, but as an Consider a pair of functions that access the same data: sub shove($) { sub prolapse() { A contrived example, of course, but until now this could only have been Pete |
From [Unknown Contact. See original ticket]our() doesn't have any "local" component in it. Consider: # CASE 0: grant access to global during scope, is really like # CASE 1: (same as previous) rather than like # CASE 2: grant access to global during scope, In other words, the duration of a run-time assignment in a You'd be wanting local our $var = "fred"; if you're expecting both. (And yes, it should be "our local" in --tom |
From [Unknown Contact. See original ticket]
Because you're providing explicit access to a global variable. if ($x < 0) { if ($x > 0) { If it this aspect of my() which our() mimics--it's restricting my() is completely different. It can nest. You can have more than my() variables "belong" to private and unique lexical scopes, whereas Perl => Meaning --tom |
From @TimToadyPete Jordan writes: Or even: sub shove($) { push our @stack, shift } Of course, that's not so different from sub shove($) { push @MyPackage::stack, shift } but with C<our> you don't need to remember your own package name. Larry |
From @gsarOn Sun, 23 Jan 2000 21:38:42 PST, I wrote:
% ./perl -Ilib -Mdiagnostics -we 'our $foo; { our $foo; }' Sarathy Inline Patch-----------------------------------8<-----------------------------------
Change 4891 by gsar@auger on 2000/01/25 20:22:01
produce redeclaration warning on C<our $foo; { our $foo; ... }>
Affected files ...
... //depot/perl/op.c#246 edit
... //depot/perl/pod/perldelta.pod#134 edit
... //depot/perl/pod/perldiag.pod#118 edit
... //depot/perl/t/pragma/strict-vars#9 edit
Differences ...
==== //depot/perl/op.c#246 (text) ====
Index: perl/op.c
--- perl/op.c.~1~ Tue Jan 25 12:29:52 2000
+++ perl/op.c Tue Jan 25 12:29:52 2000
@@ -153,22 +153,39 @@
}
if (ckWARN(WARN_UNSAFE) && AvFILLp(PL_comppad_name) >= 0) {
SV **svp = AvARRAY(PL_comppad_name);
- for (off = AvFILLp(PL_comppad_name); off > PL_comppad_name_floor; off--) {
+ HV *ourstash = (PL_curstash ? PL_curstash : PL_defstash);
+ PADOFFSET top = AvFILLp(PL_comppad_name);
+ for (off = top; off > PL_comppad_name_floor; off--) {
if ((sv = svp[off])
&& sv != &PL_sv_undef
&& (SvIVX(sv) == PAD_MAX || SvIVX(sv) == 0)
+ && (PL_in_my != KEY_our
+ || ((SvFLAGS(sv) & SVpad_OUR) && GvSTASH(sv) == ourstash))
&& strEQ(name, SvPVX(sv)))
{
- if (PL_in_my != KEY_our
- || GvSTASH(sv) == (PL_curstash ? PL_curstash : PL_defstash))
+ Perl_warner(aTHX_ WARN_UNSAFE,
+ "\"%s\" variable %s masks earlier declaration in same %s",
+ (PL_in_my == KEY_our ? "our" : "my"),
+ name,
+ (SvIVX(sv) == PAD_MAX ? "scope" : "statement"));
+ --off;
+ break;
+ }
+ }
+ if (PL_in_my == KEY_our) {
+ while (off >= 0 && off <= top) {
+ if ((sv = svp[off])
+ && sv != &PL_sv_undef
+ && ((SvFLAGS(sv) & SVpad_OUR) && GvSTASH(sv) == ourstash)
+ && strEQ(name, SvPVX(sv)))
{
Perl_warner(aTHX_ WARN_UNSAFE,
- "\"%s\" variable %s masks earlier declaration in same %s",
- (PL_in_my == KEY_our ? "our" : "my"),
- name,
- (SvIVX(sv) == PAD_MAX ? "scope" : "statement"));
+ "\"our\" variable %s redeclared", name);
+ Perl_warner(aTHX_ WARN_UNSAFE,
+ "(Did you mean \"local\" instead of \"our\"?)\n");
+ break;
}
- break;
+ --off;
}
}
}
==== //depot/perl/pod/perldelta.pod#134 (text) ====
Index: perl/pod/perldelta.pod
--- perl/pod/perldelta.pod.~1~ Tue Jan 25 12:29:52 2000
+++ perl/pod/perldelta.pod Tue Jan 25 12:29:52 2000
@@ -1549,11 +1549,6 @@
=over 4
-=item "my sub" not yet implemented
-
-(F) Lexically scoped subroutines are not yet implemented. Don't try that
-yet.
-
=item "%s" variable %s masks earlier declaration in same %s
(W) A "my" or "our" variable has been redeclared in the current scope or statement,
@@ -1562,6 +1557,16 @@
until the end of the scope or until all closure referents to it are
destroyed.
+=item "my sub" not yet implemented
+
+(F) Lexically scoped subroutines are not yet implemented. Don't try that
+yet.
+
+=item "our" variable %s redeclared
+
+(W) You seem to have already declared the same global once before in the
+current lexical scope.
+
=item '!' allowed only after types %s
(F) The '!' is allowed in pack() and unpack() only after certain types.
@@ -1802,6 +1807,11 @@
See Server error.
+=item Did you mean "local" instead of "our"?
+
+(W) Remember that "our" does not localize the declared global variable.
+You have declared it again in the same lexical scope, which seems superfluous.
+
=item Document contains no data
See Server error.
==== //depot/perl/pod/perldiag.pod#118 (text) ====
Index: perl/pod/perldiag.pod
--- perl/pod/perldiag.pod.~1~ Tue Jan 25 12:29:52 2000
+++ perl/pod/perldiag.pod Tue Jan 25 12:29:52 2000
@@ -31,6 +31,14 @@
=over 4
+=item "%s" variable %s masks earlier declaration in same %s
+
+(W) A "my" or "our" variable has been redeclared in the current scope or statement,
+effectively eliminating all access to the previous instance. This is almost
+always a typographical error. Note that the earlier variable will still exist
+until the end of the scope or until all closure referents to it are
+destroyed.
+
=item "my sub" not yet implemented
(F) Lexically scoped subroutines are not yet implemented. Don't try that
@@ -42,19 +50,16 @@
to try to declare one with a package qualifier on the front. Use local()
if you want to localize a package variable.
-=item "%s" variable %s masks earlier declaration in same %s
-
-(W) A "my" or "our" variable has been redeclared in the current scope or statement,
-effectively eliminating all access to the previous instance. This is almost
-always a typographical error. Note that the earlier variable will still exist
-until the end of the scope or until all closure referents to it are
-destroyed.
-
=item "no" not allowed in expression
(F) The "no" keyword is recognized and executed at compile time, and returns
no useful value. See L<perlmod>.
+=item "our" variable %s redeclared
+
+(W) You seem to have already declared the same global once before in the
+current lexical scope.
+
=item "use" not allowed in expression
(F) The "use" keyword is recognized and executed at compile time, and returns
@@ -1284,6 +1289,11 @@
(W) You probably referred to an imported subroutine &FOO as $FOO or some such.
+=item Did you mean "local" instead of "our"?
+
+(W) Remember that "our" does not localize the declared global variable.
+You have declared it again in the same lexical scope, which seems superfluous.
+
=item Did you mean $ or @ instead of %?
(W) You probably said %hash{$key} when you meant $hash{$key} or @hash{@keys}.
==== //depot/perl/t/pragma/strict-vars#9 (text) ====
Index: perl/t/pragma/strict-vars
--- perl/t/pragma/strict-vars.~1~ Tue Jan 25 12:29:52 2000
+++ perl/t/pragma/strict-vars Tue Jan 25 12:29:52 2000
@@ -339,3 +339,18 @@
our $foo;
EXPECT
"our" variable $foo masks earlier declaration in same scope at - line 7.
+########
+
+# multiple our declarations in same scope, same package, warning
+use strict 'vars';
+use warnings;
+our $foo;
+{
+ our $foo;
+ package Foo;
+ our $foo;
+}
+EXPECT
+"our" variable $foo redeclared at - line 7.
+(Did you mean "local" instead of "our"?)
+Name "Foo::foo" used only once: possible typo at - line 9.
End of Patch. |
Migrated from rt.perl.org#2023 (status was 'resolved')
Searchable as RT2023$
The text was updated successfully, but these errors were encountered: