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