[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

Re: scared of our()



On Thu, 13 Jan 2000 16:34:32 PST, Larry Wall wrote:
>Chris Nandor writes:
>: perl -Mstrict -wle 'our $foo = 1; print $foo; package Foo; print $foo'
>: 
>: One might expect that to print 1 twice, or to die.  It does neither.  It
>: first prints $main::foo, then $Foo::foo.  I don't like this.  It scares me.
>
>That's a known bug in my patch.  Sarathy was going to fix it to act
>more like "my", since he was mucking around between stashes and pads
>anyway for threading reasons.  So it will eventually be bound only
>to $main::foo, and in this case print 1 twice as you hoped.

Here it is.


Sarathy
gsar@ActiveState.com
-----------------------------------8<-----------------------------------
Change 4801 by gsar@auger on 2000/01/14 04:16:51

	nailed "our" declarations, and better warnings on duplicate
	"our" declarations

Affected files ...

... //depot/perl/dump.c#56 edit
... //depot/perl/gv.c#83 edit
... //depot/perl/gv.h#15 edit
... //depot/perl/op.c#235 edit
... //depot/perl/pod/perlfunc.pod#129 edit
... //depot/perl/sv.c#184 edit
... //depot/perl/sv.h#49 edit
... //depot/perl/t/pragma/strict-vars#8 edit
... //depot/perl/toke.c#178 edit

Differences ...

==== //depot/perl/dump.c#56 (text) ====
Index: perl/dump.c
--- perl/dump.c.~1~	Thu Jan 13 20:16:56 2000
+++ perl/dump.c	Thu Jan 13 20:16:56 2000
@@ -1132,6 +1132,8 @@
 	Perl_dump_indent(aTHX_ level, file, "  NAMELEN = %"IVdf"\n", (IV)GvNAMELEN(sv));
 	do_hv_dump (level, file, "  GvSTASH", GvSTASH(sv));
 	Perl_dump_indent(aTHX_ level, file, "  GP = 0x%"UVxf"\n", PTR2UV(GvGP(sv)));
+	if (!GvGP(sv))
+	    break;
 	Perl_dump_indent(aTHX_ level, file, "    SV = 0x%"UVxf"\n", PTR2UV(GvSV(sv)));
 	Perl_dump_indent(aTHX_ level, file, "    REFCNT = %"IVdf"\n", (IV)GvREFCNT(sv));
 	Perl_dump_indent(aTHX_ level, file, "    IO = 0x%"UVxf"\n", PTR2UV(GvIOp(sv)));

==== //depot/perl/gv.c#83 (text) ====
Index: perl/gv.c
--- perl/gv.c.~1~	Thu Jan 13 20:16:56 2000
+++ perl/gv.c	Thu Jan 13 20:16:56 2000
@@ -533,7 +533,6 @@
 	    else if ((COP*)PL_curcop == &PL_compiling) {
 		stash = PL_curstash;
 		if (add && (PL_hints & HINT_STRICT_VARS) &&
-		    !(add & GV_ADDOUR) &&
 		    sv_type != SVt_PVCV &&
 		    sv_type != SVt_PVGV &&
 		    sv_type != SVt_PVFM &&

==== //depot/perl/gv.h#15 (text) ====
Index: perl/gv.h
--- perl/gv.h.~1~	Thu Jan 13 20:16:56 2000
+++ perl/gv.h	Thu Jan 13 20:16:56 2000
@@ -141,4 +141,3 @@
 #define GV_ADDWARN	0x04	/* add, but warn if symbol wasn't already there */
 #define GV_ADDINEVAL	0x08	/* add, as though we're doing so within an eval */
 #define GV_NOINIT	0x10	/* add, but don't init symbol, if type != PVGV */
-#define GV_ADDOUR	0x20	/* add "our" variable */

==== //depot/perl/op.c#235 (text) ====
Index: perl/op.c
--- perl/op.c.~1~	Thu Jan 13 20:16:56 2000
+++ perl/op.c	Thu Jan 13 20:16:56 2000
@@ -159,11 +159,15 @@
 		&& (SvIVX(sv) == PAD_MAX || SvIVX(sv) == 0)
 		&& strEQ(name, SvPVX(sv)))
 	    {
-		Perl_warner(aTHX_ WARN_UNSAFE,
+		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"));
+		}
 		break;
 	    }
 	}
@@ -181,8 +185,11 @@
 	SvSTASH(sv) = (HV*)SvREFCNT_inc(PL_in_my_stash);
 	PL_sv_objcount++;
     }
-    if (PL_in_my == KEY_our)
+    if (PL_in_my == KEY_our) {
+	(void)SvUPGRADE(sv, SVt_PVGV);
+	GvSTASH(sv) = (HV*)SvREFCNT_inc(PL_curstash ? PL_curstash : PL_defstash);
 	SvFLAGS(sv) |= SVpad_OUR;
+    }
     av_store(PL_comppad_name, off, sv);
     SvNVX(sv) = (NV)PAD_MAX;
     SvIVX(sv) = 0;			/* Not yet introduced--see newSTATEOP */
@@ -250,14 +257,17 @@
 		    SvNVX(namesv) = (NV)PL_curcop->cop_seq;
 		    SvIVX(namesv) = PAD_MAX;	/* A ref, intro immediately */
 		    SvFAKE_on(namesv);		/* A ref, not a real var */
-		    if (SvFLAGS(sv) & SVpad_OUR)/* An "our" variable */
-			SvFLAGS(namesv) |= SVpad_OUR;
 		    if (SvOBJECT(sv)) {		/* A typed var */
 			SvOBJECT_on(namesv);
 			(void)SvUPGRADE(namesv, SVt_PVMG);
 			SvSTASH(namesv) = (HV*)SvREFCNT_inc((SV*)SvSTASH(sv));
 			PL_sv_objcount++;
 		    }
+		    if (SvFLAGS(sv) & SVpad_OUR) { /* An "our" variable */
+			SvFLAGS(namesv) |= SVpad_OUR;
+			(void)SvUPGRADE(namesv, SVt_PVGV);
+			GvSTASH(namesv) = (HV*)SvREFCNT_inc((SV*)GvSTASH(sv));
+		    }
 		    if (CvANON(PL_compcv) || SvTYPE(PL_compcv) == SVt_PVFM) {
 			/* "It's closures all the way down." */
 			CvCLONE_on(PL_compcv);

==== //depot/perl/pod/perlfunc.pod#129 (text) ====
Index: perl/pod/perlfunc.pod
--- perl/pod/perlfunc.pod.~1~	Thu Jan 13 20:16:56 2000
+++ perl/pod/perlfunc.pod	Thu Jan 13 20:16:56 2000
@@ -2788,6 +2788,34 @@
 (But only within the lexical scope of the C<our> declaration.  In this
 it differs from "use vars", which is package scoped.)
 
+An C<our> declaration declares a global variable that will be visible
+across its entire lexical scope, even across package boundaries.  The
+package in which the variable is entered is determined at the point
+of the declaration, not at the point of use.  This means the following
+behavior holds:
+
+    package Foo;
+    our $bar;		# declares $Foo::bar for rest of lexical scope
+    $bar = 20;
+
+    package Bar;
+    print $bar;		# prints 20
+
+Multiple C<our> declarations in the same lexical scope are allowed
+if they are in different packages.  If they happened to be in the same
+package, Perl will emit warnings if you have asked for them.
+
+    use warnings;
+    package Foo;
+    our $bar;		# declares $Foo::bar for rest of lexical scope
+    $bar = 20;
+
+    package Bar;
+    our $bar = 30;	# declares $Bar::bar for rest of lexical scope
+    print $bar;		# prints 30
+
+    our $bar;		# emits warning
+
 =item pack TEMPLATE,LIST
 
 Takes a LIST of values and converts it into a string using the rules

==== //depot/perl/sv.c#184 (text) ====
Index: perl/sv.c
--- perl/sv.c.~1~	Thu Jan 13 20:16:56 2000
+++ perl/sv.c	Thu Jan 13 20:16:56 2000
@@ -7303,7 +7303,7 @@
 static void
 do_clean_named_objs(pTHXo_ SV *sv)
 {
-    if (SvTYPE(sv) == SVt_PVGV) {
+    if (SvTYPE(sv) == SVt_PVGV && GvGP(sv)) {
 	if ( SvOBJECT(GvSV(sv)) ||
 	     GvAV(sv) && SvOBJECT(GvAV(sv)) ||
 	     GvHV(sv) && SvOBJECT(GvHV(sv)) ||

==== //depot/perl/sv.h#49 (text) ====
Index: perl/sv.h
--- perl/sv.h.~1~	Thu Jan 13 20:16:56 2000
+++ perl/sv.h	Thu Jan 13 20:16:56 2000
@@ -156,8 +156,7 @@
 
 /* Some private flags. */
 
-#define SVpad_OUR	0x80000000	/* pad name is "our" instead of "my" */
-
+/* SVpad_OUR may be set on SVt_PV{NV,MG,GV} types */
 #define SVpad_OUR	0x80000000	/* pad name is "our" instead of "my" */
 
 #define SVf_IVisUV	0x80000000	/* use XPVUV instead of XPVIV */

==== //depot/perl/t/pragma/strict-vars#8 (text) ====
Index: perl/t/pragma/strict-vars
--- perl/t/pragma/strict-vars.~1~	Thu Jan 13 20:16:56 2000
+++ perl/t/pragma/strict-vars	Thu Jan 13 20:16:56 2000
@@ -307,3 +307,35 @@
 EXPECT
 2
 1
+########
+
+# "nailed" our declaration visibility across package boundaries
+use strict 'vars';
+our $foo;
+$foo = 20;
+package Foo;
+print $foo, "\n";
+EXPECT
+20
+########
+
+# multiple our declarations in same scope, different packages, no warning
+use strict 'vars';
+use warnings;
+our $foo;
+${foo} = 10;
+package Foo;
+our $foo = 20;
+print $foo, "\n";
+EXPECT
+20
+########
+
+# multiple our declarations in same scope, same package, warning
+use strict 'vars';
+use warnings;
+our $foo;
+${foo} = 10;
+our $foo;
+EXPECT
+"our" variable $foo masks earlier declaration in same scope at - line 7.

==== //depot/perl/toke.c#178 (text) ====
Index: perl/toke.c
--- perl/toke.c.~1~	Thu Jan 13 20:16:56 2000
+++ perl/toke.c	Thu Jan 13 20:16:56 2000
@@ -2015,15 +2015,19 @@
 	    }
 #endif /* USE_THREADS */
 	    if ((tmp = pad_findmy(PL_tokenbuf)) != NOT_IN_PAD) {
+		SV *namesv = AvARRAY(PL_comppad_name)[tmp];
 		/* might be an "our" variable" */
-		if (SvFLAGS(AvARRAY(PL_comppad_name)[tmp]) & SVpad_OUR) {
+		if (SvFLAGS(namesv) & SVpad_OUR) {
 		    /* build ops for a bareword */
-		    yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(PL_tokenbuf+1, 0));
+		    SV *sym = newSVpv(HvNAME(GvSTASH(namesv)),0);
+		    sv_catpvn(sym, "::", 2);
+		    sv_catpv(sym, PL_tokenbuf+1);
+		    yylval.opval = (OP*)newSVOP(OP_CONST, 0, sym);
 		    yylval.opval->op_private = OPpCONST_ENTERED;
-		    gv_fetchpv(PL_tokenbuf+1,
+		    gv_fetchpv(SvPVX(sym),
 			(PL_in_eval
-			    ? (GV_ADDMULTI | GV_ADDINEVAL | GV_ADDOUR)
-			    : GV_ADDOUR
+			    ? (GV_ADDMULTI | GV_ADDINEVAL)
+			    : TRUE
 			),
 			((PL_tokenbuf[0] == '$') ? SVt_PV
 			 : (PL_tokenbuf[0] == '@') ? SVt_PVAV
End of Patch.


References to:
Larry Wall <larry@wall.org>

[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]