[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: