Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Whither 5.6.3?

10 views
Skip to first unread message

Yitzchak Scott-Thoennes

unread,
Jan 25, 2004, 9:26:51 PM1/25/04
to perl5-...@perl.org
Are there plans for integrating the 5.6.2 changes into 5.6.x and
preparing for a 5.6.3? If so, I'd like to see this (from 5.8.0 and
onward) included, in case Dave (was it Dave? Its been a while)
follows through on his mutterings about fixing this someday.

--- perl-5.6.2/pod/perlsyn.pod.orig 2003-07-30 07:32:51.000000000 -0700
+++ perl-5.6.2/pod/perlsyn.pod 2004-01-25 02:46:49.414512000 -0800
@@ -124,6 +124,13 @@
} while $x++ <= $z;
}

+B<NOTE:> The behaviour of a C<my> statement modified with a statement
+modifier conditional or loop construct (e.g. C<my $x if ...>) is
+B<undefined>. The value of the C<my> variable may be C<undef>, any
+previously assigned value, or possibly anything else. Don't rely on
+it. Future versions of perl might do something different from the
+version of perl you try it out on. Here be dragons.
+
=head2 Compound statements

In Perl, a sequence of statements that defines a scope is called a block.

Yitzchak Scott-Thoennes

unread,
Jan 26, 2004, 8:49:15 PM1/26/04
to perl5-...@perl.org
On Tue, Jan 27, 2004 at 01:00:37AM +0000, Dave Mitchell <da...@fdisolutions.com> wrote:

> On Sun, Jan 25, 2004 at 06:26:51PM -0800, Yitzchak Scott-Thoennes wrote:
> > Are there plans for integrating the 5.6.2 changes into 5.6.x and
> > preparing for a 5.6.3? If so, I'd like to see this (from 5.8.0 and
> > onward) included, in case Dave (was it Dave? Its been a while)
>
> 'twas me. In fact I actually I have (had?) a patch that fixes this,
> but I decided the performance problems were too great. It basically
> moved all the SAVECLEARSV's out from the individual padsv ops to the
> start of the block. This was really fine and dandy and fast, except for
> code like:
>
> while (<>) {
> next unless /..../; # assume this branch taken 99% of the time
> my ($lots, $of, $lexical, $variables, ....);
> # ... lots of code
> }
>
> In the old regime, the padsv ops (and the SAVECLEARSV's) were skipped
> 99% of the time; with my patch you got hit each time round the loop,
> resulting in a big performance hit. Since the above code is reasonably
> canonical, I thought this was probably a bad idea.

>
> > follows through on his mutterings about fixing this someday.
> >
> > --- perl-5.6.2/pod/perlsyn.pod.orig 2003-07-30 07:32:51.000000000 -0700
> > +++ perl-5.6.2/pod/perlsyn.pod 2004-01-25 02:46:49.414512000 -0800
> > @@ -124,6 +124,13 @@
> > } while $x++ <= $z;
> > }
> >
> > +B<NOTE:> The behaviour of a C<my> statement modified with a statement
> > +modifier conditional or loop construct (e.g. C<my $x if ...>) is
> > +B<undefined>. The value of the C<my> variable may be C<undef>, any
> > +previously assigned value, or possibly anything else. Don't rely on
> > +it. Future versions of perl might do something different from the
> > +version of perl you try it out on. Here be dragons.
> > +
>
> Yes, I've noticed that one poster on perlmonks actually has
> in his sig an example of using this bug to create static vars.
> The sooner this is stamped out the better!

If it were just people misusing it intentionally, that wouldn't be a
problem. It's tripping over it accidentally that really gets bad.
Even knowing about the problem, you can stare at code and not see
it.

Can you not just put an extra void-context padsv op in with a
special-case it in perly.y? That wouldn't fix a my() embedded in
some code, but would catch most cases. (Umm, I see padsv isn't
context aware.)

Yitzchak Scott-Thoennes

unread,
Jan 27, 2004, 5:11:55 PM1/27/04
to Rafael Garcia-Suarez, perl5-...@perl.org
On Tue, Jan 27, 2004 at 10:29:04PM +0100, Rafael Garcia-Suarez <rgarci...@free.fr> wrote:
> Yitzchak Scott-Thoennes wrote:
> > Are there plans for integrating the 5.6.2 changes into 5.6.x and
> > preparing for a 5.6.3? If so, I'd like to see this (from 5.8.0 and
> > onward) included, in case Dave (was it Dave? Its been a while)
> > follows through on his mutterings about fixing this someday.
>
> Good idea. Thanks, applied.

To which branch?

Dave Mitchell

unread,
Jan 26, 2004, 8:00:37 PM1/26/04
to Yitzchak Scott-Thoennes, perl5-...@perl.org
On Sun, Jan 25, 2004 at 06:26:51PM -0800, Yitzchak Scott-Thoennes wrote:
> Are there plans for integrating the 5.6.2 changes into 5.6.x and
> preparing for a 5.6.3? If so, I'd like to see this (from 5.8.0 and
> onward) included, in case Dave (was it Dave? Its been a while)

'twas me. In fact I actually I have (had?) a patch that fixes this,


but I decided the performance problems were too great. It basically
moved all the SAVECLEARSV's out from the individual padsv ops to the
start of the block. This was really fine and dandy and fast, except for
code like:

while (<>) {
next unless /..../; # assume this branch taken 99% of the time
my ($lots, $of, $lexical, $variables, ....);
# ... lots of code
}

In the old regime, the padsv ops (and the SAVECLEARSV's) were skipped
99% of the time; with my patch you got hit each time round the loop,
resulting in a big performance hit. Since the above code is reasonably
canonical, I thought this was probably a bad idea.

> follows through on his mutterings about fixing this someday.


>
> --- perl-5.6.2/pod/perlsyn.pod.orig 2003-07-30 07:32:51.000000000 -0700
> +++ perl-5.6.2/pod/perlsyn.pod 2004-01-25 02:46:49.414512000 -0800
> @@ -124,6 +124,13 @@
> } while $x++ <= $z;
> }
>
> +B<NOTE:> The behaviour of a C<my> statement modified with a statement
> +modifier conditional or loop construct (e.g. C<my $x if ...>) is
> +B<undefined>. The value of the C<my> variable may be C<undef>, any
> +previously assigned value, or possibly anything else. Don't rely on
> +it. Future versions of perl might do something different from the
> +version of perl you try it out on. Here be dragons.
> +

Yes, I've noticed that one poster on perlmonks actually has


in his sig an example of using this bug to create static vars.
The sooner this is stamped out the better!


--
This email is confidential, and now that you have read it you are legally
obliged to shoot yourself. Or shoot a lawyer, if you prefer. If you have
received this email in error, place it in its original wrapping and return
for a full refund. By opening this email, you accept that Elvis lives.

Yves Orton

unread,
Jan 28, 2004, 12:10:40 PM1/28/04
to Dave Mitchell, Yitzchak Scott-Thoennes, perl5-...@perl.org
> Yes, I've noticed that one poster on perlmonks actually has
> in his sig an example of using this bug to create static vars.
> The sooner this is stamped out the better!

Its usage is widespread. Most people consider it a feature. Id agree its a
bug, but stamping it out is not going to be a simple matter IMO.

Yves

Yitzchak Scott-Thoennes

unread,
Jan 28, 2004, 1:25:49 PM1/28/04
to Orton, Yves, Dave Mitchell, perl5-...@perl.org

If it's a feature, it's not a good one. In addition to the problem with
people doing it accidentally, having people assume it makes "static"
variables is also bad.

Consider:
================================
use strict;
use warnings;

my @static; # keep track of all parms ever passed to foo

sub addfoo { foo(qw/foo bar baz/) }

sub foo {
# my @static if 0; # keep track of all parms ever passed to foo
push @static, @_;
print "so far, we've got: @static\n";
if (@static < 6) {
print "but we need more, let's add some.\n";
addfoo;
}
}

addfoo;
================================

The first way of creating a static (a file-scoped lexical) works. The
my if way doesn't, because it's not per-sub, it's per-pad.

Yves Orton

unread,
Jan 29, 2004, 12:10:32 PM1/29/04
to Yitzchak Scott-Thoennes, Dave Mitchell, perl5-...@perl.org
> > Its usage is widespread. Most people consider it a feature. Id agree
its a
> > bug, but stamping it out is not going to be a simple matter IMO.
>
> If it's a feature, it's not a good one. In addition to the problem with
> people doing it accidentally, having people assume it makes "static"
> variables is also bad

....

Oh, dont get me wrong. Make it a syntax error, or a warning or whatever. I
only commented becuase I think the meme is wider spread than one might think
and that it may affect more code than one might think.

But I know that personally Ive been bitten by it and would have loved a
warning.

also a warning would be nice for

my $foo=$_ for (1..10);

which doesnt do anything like what it looks like it should do.


Yves

Dave Mitchell

unread,
Jan 31, 2004, 8:59:00 PM1/31/04
to Orton, Yves, Yitzchak Scott-Thoennes, perl5-...@perl.org
On Thu, Jan 29, 2004 at 05:10:32PM -0000, Orton, Yves wrote:

[discussion of C<my $x if $condition> ]

> Oh, dont get me wrong. Make it a syntax error, or a warning or whatever. I
> only commented becuase I think the meme is wider spread than one might think
> and that it may affect more code than one might think.
>
> But I know that personally Ive been bitten by it and would have loved a
> warning.

The patch below attempts to give such a warning. I'll apply it in a couple
of days if no one objects.

$ ./perl -we 'my $x if $a'
Use of my in conditional deprecated at -e line 1.

If detects and/or/if/unless as simple statements, eg the following all
give the a warning:

my $x if $a;
$a && (my $x = 1);
my ($x,@y) = (1,2,3) unless $a;
$a || (my ($x,@y) = (1,2,3));

but the following doesn't warn:

if ($a && (my $foo = ...)) { print $foo }

This patch threw up quite a lot of problems in the test suite, which is an
indication that there's a *lot* of code out there about to get noisy.
Here is a list of the major ones, along with sample snippets of code

Use of my in conditional deprecated at ../lib/IO/Handle.pm line 497.
Use of my in conditional deprecated at ../lib/IO/Handle.pm line 504.
Use of my in conditional deprecated at ../lib/IO/Handle.pm line 511.
Use of my in conditional deprecated at ../lib/IO/Handle.pm line 518.
Use of my in conditional deprecated at ../lib/IO/Handle.pm line 525.
Use of my in conditional deprecated at ../lib/IO/Handle.pm line 532.
Use of my in conditional deprecated at ../lib/IO/Handle.pm line 607.

my $tell = tell qualify($_[0], caller) if ref($_[0]);


Use of my in conditional deprecated at ../lib/B/Deparse.pm line 1089.

my $nseq = $self->find_scope_st($root->sibling) if ${$root->sibling};


Use of my in conditional deprecated at ../lib/IO/Pipe.pm line 125

my $pid = $me->_doit(1, $fh, @_)
if(@_);


Use of my in conditional deprecated at ../lib/ExtUtils/Liblist/Kid.pm line 230.
Use of my in conditional deprecated at ../lib/ExtUtils/Liblist/Kid.pm line 231.
Use of my in conditional deprecated at ../lib/ExtUtils/Liblist/Kid.pm line 232.

my $VC = 1 if $cc =~ /^cl/i;
my $BC = 1 if $cc =~ /^bcc/i;
my $GC = 1 if $cc =~ /^gcc/i;


Use of my in conditional deprecated at ../lib/ExtUtils/MM_NW5.pm line 35.
Use of my in conditional deprecated at ../lib/ExtUtils/MM_NW5.pm line 36.
Use of my in conditional deprecated at ../lib/ExtUtils/MM_NW5.pm line 37.

my $BORLAND = 1 if $Config{'cc'} =~ /^bcc/i;
my $GCC = 1 if $Config{'cc'} =~ /^gcc/i;
my $DMAKE = 1 if $Config{'make'} =~ /^dmake/i;


Use of my in conditional deprecated at ../lib/ExtUtils/MM_Win95.pm line 10.
Use of my in conditional deprecated at ../lib/ExtUtils/MM_Win95.pm line 11.

my $DMAKE = 1 if $Config{'make'} =~ /^dmake/i;
my $NMAKE = 1 if $Config{'make'} =~ /^nmake/i;


Use of my in conditional deprecated at ../utils/h2xs line 671.

my %const_xsub = map { $_,1 } split(/,+/, $opt_s) if $opt_s;


Use of my in conditional deprecated at ../lib/Net/NNTP.pm line 24.
Use of my in conditional deprecated at ../lib/Net/SMTP.pm line 27.
Use of my in conditional deprecated at ../lib/Net/POP3.pm line 24.

my $host = shift if @_ % 2;


Use of my in conditional deprecated at ../lib/Pod/Parser.pm line 1158.

my ($in_fh, $out_fh) = (gensym, gensym) if ($] < 5.6);


Use of my in conditional deprecated at ../lib/Test/Harness.pm line 466

my @dir_files = _globdir $Files_In_Dir if defined $Files_In_Dir;


> also a warning would be nice for
>
> my $foo=$_ for (1..10);
>
> which doesnt do anything like what it looks like it should do.

I'll worry about that one later!

Dave.

--
Nothing ventured, nothing lost.

--- opcode.pl- Sat Jan 31 23:08:40 2004
+++ opcode.pl Sun Feb 1 00:40:46 2004
@@ -684,8 +684,8 @@
reset symbol reset ck_fun is% S?

lineseq line sequence ck_null @
-nextstate next statement ck_null s;
-dbstate debug next statement ck_null s;
+nextstate next statement ck_state s;
+dbstate debug next statement ck_state s;
unstack iteration finalizer ck_null s0
enter block entry ck_null 0
leave block exit ck_null @
--- op.c- Sat Jan 31 22:57:27 2004
+++ op.c Sun Feb 1 01:36:30 2004
@@ -3305,7 +3305,7 @@
}
}

- return prepend_elem(OP_LINESEQ, (OP*)cop, o);
+ return prepend_elem(OP_LINESEQ, (OP*)cop, CHECKOP(cop->op_type, o));
}


@@ -5938,6 +5938,43 @@
}

OP *
+Perl_ck_state(pTHX_ OP *o)
+{
+ /* **NB** o is actually the sibling of the state op */
+
+ /* warn on C<my $x=1 if foo;> , C<$a && my $x=1;> style statements */
+ OP *kid;
+ if (!o || o->op_type != OP_NULL || !(o->op_flags & OPf_KIDS))
+ return o;
+ kid = cUNOPo->op_first;
+ if (!(kid->op_type == OP_AND || kid->op_type == OP_OR))
+ return o;
+ kid = kUNOP->op_first->op_sibling;
+ if (kid->op_type == OP_SASSIGN)
+ kid = kBINOP->op_first->op_sibling;
+ else if (kid->op_type == OP_AASSIGN)
+ kid = kBINOP->op_first->op_sibling;
+
+ if (kid->op_type == OP_LIST
+ || (kid->op_type == OP_NULL && kid->op_targ == OP_LIST))
+ {
+ kid = kUNOP->op_first;
+ if (kid->op_type == OP_PUSHMARK)
+ kid = kid->op_sibling;
+ }
+ if ((kid->op_type == OP_PADSV || kid->op_type == OP_PADAV
+ || kid->op_type == OP_PADHV)
+ && (kid->op_private & OPpLVAL_INTRO)
+ && (ckWARN(WARN_DEPRECATED)))
+ {
+ Perl_warner(aTHX_ packWARN(WARN_DEPRECATED),
+ "Use of my in conditional deprecated");
+ }
+ return o;
+}
+
+
+OP *
Perl_ck_subr(pTHX_ OP *o)
{
OP *prev = ((cUNOPo->op_first->op_sibling)
--- t/lib/warnings/op- Sat Jan 31 23:27:57 2004
+++ t/lib/warnings/op Sun Feb 1 01:53:18 2004
@@ -1050,3 +1050,60 @@
Useless localization of substr at - line 48.
Useless localization of match position at - line 49.
Useless localization of vec at - line 50.
+########
+# op.c
+use warnings 'deprecated';
+our $a;
+my $x1 if $a;
+my @x2 if $a;
+my %x3 if $a;
+my ($x4) if $a;
+my ($x5,@x6, %x7) if $a;
+my @x8 if ($a+$a);
+my $x9 = 1+$a if $a;
+my ($x10,@x11) = ($a,$a+$a) if $a;
+my ($x12) = 1 if $a;
+my $y1 unless $a;
+my @y2 unless $a;
+my %y3 unless $a;
+my ($y4) unless $a;
+my ($y5,@y6, %y7) unless $a;
+my @y8 unless ($a+$a);
+$a && my $z1;
+$a && my (%z2);
+$a || my @z3;
+$a || my (%z4);
+$a || my (%z4,$z5);
+$a && (my $z6 = 1);
+$a && (my ($z7,@z8) = (1,2,3));
+
+# these shouldn't warn
+our $x if $a;
+our $x unless $a;
+if ($a) { my $w1 }
+if (my $w2) { $a=1 }
+if ($a && (my $w3 = 1)) {$a = 2}
+
+EXPECT
+Use of my in conditional deprecated at - line 4.
+Use of my in conditional deprecated at - line 5.
+Use of my in conditional deprecated at - line 6.
+Use of my in conditional deprecated at - line 7.
+Use of my in conditional deprecated at - line 8.
+Use of my in conditional deprecated at - line 9.
+Use of my in conditional deprecated at - line 10.
+Use of my in conditional deprecated at - line 11.
+Use of my in conditional deprecated at - line 12.
+Use of my in conditional deprecated at - line 13.
+Use of my in conditional deprecated at - line 14.
+Use of my in conditional deprecated at - line 15.
+Use of my in conditional deprecated at - line 16.
+Use of my in conditional deprecated at - line 17.
+Use of my in conditional deprecated at - line 18.
+Use of my in conditional deprecated at - line 19.
+Use of my in conditional deprecated at - line 20.
+Use of my in conditional deprecated at - line 21.
+Use of my in conditional deprecated at - line 22.
+Use of my in conditional deprecated at - line 23.
+Use of my in conditional deprecated at - line 24.
+Use of my in conditional deprecated at - line 25.
--- pod/perldiag.pod- Sat Jan 31 23:47:54 2004
+++ pod/perldiag.pod Sun Feb 1 01:30:07 2004
@@ -4282,6 +4282,24 @@
it already went past any symlink you are presumably trying to look for.
The operation returned C<undef>. Use a filename instead.

+=item Use of my in conditional deprecated
+
+(D deprecated) You used a C<my> declaration within a conditional
+expression of some sort, such as C<my $x=1 if foo> or C<foo && (my $x = 1)>.
+Perl's run-time behaviour in such constructs is currently undefined, but
+typically causes the variable not be be cleared at the end of scope and
+to retain its old value the next time the scope is entered. Some people
+have been making use of this "feature" to implement a type of static
+variable. We intend to change this behaviour in a future release, so
+don't rely on it.
+
+To work around this warning, move the declaration outside the expression,
+eg
+
+ my $x;
+ $x = 1 if foo;
+
+
=item Use of "package" with no arguments is deprecated

(D deprecated) You used the C<package> keyword without specifying a package

Rafael Garcia-Suarez

unread,
Feb 1, 2004, 4:52:09 PM2/1/04
to Dave Mitchell, Orton, Yves, Yitzchak Scott-Thoennes, perl5-...@perl.org
Dave Mitchell <da...@fdisolutions.com> wrote:
> The patch below attempts to give such a warning. I'll apply it in a couple
> of days if no one objects.
>
> $ ./perl -we 'my $x if $a'
> Use of my in conditional deprecated at -e line 1.
...

> This patch threw up quite a lot of problems in the test suite, which is an
> indication that there's a *lot* of code out there about to get noisy.
> Here is a list of the major ones, along with sample snippets of code

This is a bit worrying. Do all those warnings indicate potential bugs,
only waiting to be discovered ?

Anyway, this indicates that "my $x = 1 if $foo" is a construct people
want to use in perl. Maybe a better fix would be make it equivalent
to the DWIM interpretation, "my $x;$x = 1 if $foo". But a deprecation
cycle might be a good idea, too...

Dave Mitchell

unread,
Feb 1, 2004, 5:00:53 PM2/1/04
to Rafael Garcia-Suarez, Orton, Yves, Yitzchak Scott-Thoennes, perl5-...@perl.org
On Sun, Feb 01, 2004 at 10:52:09PM +0100, Rafael Garcia-Suarez wrote:
> Dave Mitchell <da...@fdisolutions.com> wrote:
> > The patch below attempts to give such a warning. I'll apply it in a couple
> > of days if no one objects.
> >
> > $ ./perl -we 'my $x if $a'
> > Use of my in conditional deprecated at -e line 1.
> ...
> > This patch threw up quite a lot of problems in the test suite, which is an
> > indication that there's a *lot* of code out there about to get noisy.
> > Here is a list of the major ones, along with sample snippets of code
>
> This is a bit worrying. Do all those warnings indicate potential bugs,
> only waiting to be discovered ?

I think quite a few of them were at the top of a module, so the lexical
never enters scope more than once. In that case the bug doesn't rear its
ugly head, eg

package Foo::Bar;
my $has_feature_foo = 1 if $config{...};
...

But some of them are certainly bug canditdates. Or at least will-break-if-
we-fix-the behaviour-of-myif candidates.

> Anyway, this indicates that "my $x = 1 if $foo" is a construct people
> want to use in perl. Maybe a better fix would be make it equivalent
> to the DWIM interpretation, "my $x;$x = 1 if $foo". But a deprecation
> cycle might be a good idea, too...

My proposed patch is meant to kick-start the cycle :-)

It's a while ago now, but I had a few stabs at actually fixing this,
and I seem to recall that all my approaches had problems. Because we
want to migrate the the 'my' bit outside the conditional expression,
but we mustn't screw up the scope, eg

my $x = 1 if foo;
=>
my $x; $x = 1 if foo; # easy


if ( my $cond = ($foo && (my $val = foo()))) { print $val }
=>
???

--
Fire extinguisher (n) a device for holding open fire doors.

Yitzchak Scott-Thoennes

unread,
Feb 1, 2004, 5:24:22 PM2/1/04
to Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org
On Sun, Feb 01, 2004 at 10:00:53PM +0000, Dave Mitchell <da...@fdisolutions.com> wrote:
> On Sun, Feb 01, 2004 at 10:52:09PM +0100, Rafael Garcia-Suarez wrote:
> >
> > This is a bit worrying. Do all those warnings indicate potential bugs,
> > only waiting to be discovered ?
>
> I think quite a few of them were at the top of a module, so the lexical
> never enters scope more than once. In that case the bug doesn't rear its
> ugly head, eg

Most of them seemed to involve an unchanging value being tested with if.
These presumably wouldn't be a problem. The libnet ones did look buggy
at first glance (e.g. calling the subs with varying numbers of parameters
may not always do what it should); the SelectSaver ones I wasn't sure about.

> But some of them are certainly bug canditdates. Or at least will-break-if-
> we-fix-the behaviour-of-myif candidates.

Which? Looked more to me like "will-be-fixed-if-we-fix-myif" cases.

> > Anyway, this indicates that "my $x = 1 if $foo" is a construct people
> > want to use in perl. Maybe a better fix would be make it equivalent
> > to the DWIM interpretation, "my $x;$x = 1 if $foo". But a deprecation
> > cycle might be a good idea, too...

It's too easy to make the mistake; I don't think we have the luxury of
a deprecation cycle. We've had a doc warning about it since 5.8.0.
If it's fixed (to do your DWIM interpretation) the fix should go into
the next 5.8.x release (IMO).

> My proposed patch is meant to kick-start the cycle :-)
>
> It's a while ago now, but I had a few stabs at actually fixing this,
> and I seem to recall that all my approaches had problems. Because we
> want to migrate the the 'my' bit outside the conditional expression,
> but we mustn't screw up the scope, eg
>
> my $x = 1 if foo;
> =>
> my $x; $x = 1 if foo; # easy

The easy case will cover almost all of the bugs. Go for it, if you can.

A thought: most of the point of providing a deprecation cycle would be
for those intentionally misusing it, and that will almost always look
like my $x if 0; Can you exclude that case from the fix and give a
deprecated warning? (But just in maint; fix all possible cases in blead.)

> if ( my $cond = ($foo && (my $val = foo()))) { print $val }
> =>
> ???

Ouch.

Yves Orton

unread,
Feb 2, 2004, 5:46:40 AM2/2/04
to Dave Mitchell, Orton, Yves, Yitzchak Scott-Thoennes, perl5-...@perl.org
> > also a warning would be nice for
> >
> > my $foo=$_ for (1..10);
> >
> > which doesnt do anything like what it looks like it should do.
>
> I'll worry about that one later!


Thanks a lot Dave. This all is a good step forward IMO, the for modifer
variant is just icing on the cake...

Yves

Yves Orton

unread,
Feb 2, 2004, 6:07:22 AM2/2/04
to Yitzchak Scott-Thoennes, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org
> > But some of them are certainly bug canditdates. Or at least
> will-break-if-
> > we-fix-the behaviour-of-myif candidates.
>
> Which? Looked more to me like "will-be-fixed-if-we-fix-myif" cases.

Agreed.



> > > Anyway, this indicates that "my $x = 1 if $foo" is a
> construct people
> > > want to use in perl. Maybe a better fix would be make it
> equivalent
> > > to the DWIM interpretation, "my $x;$x = 1 if $foo". But a
> deprecation
> > > cycle might be a good idea, too...
>
> It's too easy to make the mistake; I don't think we have the luxury of
> a deprecation cycle. We've had a doc warning about it since 5.8.0.
> If it's fixed (to do your DWIM interpretation) the fix should go into
> the next 5.8.x release (IMO).

Also Id argue that this feature is encouraged by false lazyness. They have
other unambiguous ways of accomplishing the task, so id say make it go away
totally. Sure some people will moan, but I think its the right decision. If
modifier to make switchable statics are just evil.

> A thought: most of the point of providing a deprecation cycle would be
> for those intentionally misusing it, and that will almost always look
> like my $x if 0; Can you exclude that case from the fix and give a
> deprecated warning? (But just in maint; fix all possible
> cases in blead.)

Maybe im too hard ass, but I say make it go away totally. I bet itll result
in some less bugy code in the end.

>
> > if ( my $cond = ($foo && (my $val = foo()))) { print $val }
> > =>
> > ???
>
> Ouch.

Umm can anybody explain why this is a problem? Because both $cond and $val
are scoped to the if, there is no problem here. The only place that a
problem comes up is in modifier form becuase in the modifer form the my
exists at the scope level that encloses the if, not the scope level enclosed
by the if.

For instance the following code shows how the modifer form has problems but
not the above code:

#!perl -l
sub foo{return $foo ? "foo" : "bar"};
sub bar{my $x=$_[1] if !$_[0]; "\$x:$x"};
for $foo (0,1,0,1) {
print "\n\$foo=$foo";


if ( my $cond = ($foo && (my $val = foo())))

{ print "T:\$val:$val" }
else
{print "F:\$val:$val"}

print "bar($foo):".bar($foo,($foo+1) *10);
print "bar(0):".bar(0,($foo+1) *10);
}
__END__

$foo=0
F:$val:
bar(0):$x:10
bar(0):$x:10

$foo=1
T:$val:foo
bar(1):$x:
bar(0):$x:20

$foo=0
F:$val:
bar(0):$x:10
bar(0):$x:10

$foo=1
T:$val:foo
bar(1):$x:
bar(0):$x:20

Id love to know what im missing that makes the normal if a problem.

Cheers,
Yves

Tim Bunce

unread,
Feb 2, 2004, 10:12:00 AM2/2/04
to Yitzchak Scott-Thoennes, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org
On Sun, Feb 01, 2004 at 02:24:22PM -0800, Yitzchak Scott-Thoennes wrote:
> It's too easy to make the mistake; I don't think we have the luxury of
> a deprecation cycle. We've had a doc warning about it since 5.8.0.
> If it's fixed (to do your DWIM interpretation) the fix should go into
> the next 5.8.x release (IMO).

I disagree. This change, if it happens at all, belongs in 5.9 and up.

Don't make existing production perl's moan about a construct that's
in widespread use. That's putting correctness over pragmatism and
we won't be thanked for it.

Tim.

Yitzchak Scott-Thoennes

unread,
Feb 2, 2004, 2:17:57 PM2/2/04
to Tim Bunce, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org

Do you have information on how widespread it is? That would be helpful.

Nicholas Clark

unread,
Feb 2, 2004, 2:36:26 PM2/2/04
to Tim Bunce, Yitzchak Scott-Thoennes, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org
On Mon, Feb 02, 2004 at 03:12:00PM +0000, Tim Bunce wrote:
> On Sun, Feb 01, 2004 at 02:24:22PM -0800, Yitzchak Scott-Thoennes wrote:
> > It's too easy to make the mistake; I don't think we have the luxury of
> > a deprecation cycle. We've had a doc warning about it since 5.8.0.
> > If it's fixed (to do your DWIM interpretation) the fix should go into
> > the next 5.8.x release (IMO).
>
> I disagree. This change, if it happens at all, belongs in 5.9 and up.

I'm uneasy about it in the first place (although I admit I've only skimmed
the thread). What's Larry's view on changing this prior to perl6?

> Don't make existing production perl's moan about a construct that's
> in widespread use. That's putting correctness over pragmatism and
> we won't be thanked for it.

I agree. I don't see a place for changes of this nature in a maintenance
release, given that maintenance releases are meant to be drop-in upgrades
for existing versions.

Nicholas Clark

Rafael Garcia-Suarez

unread,
Feb 2, 2004, 2:49:36 PM2/2/04
to Nicholas Clark, Tim Bunce, Yitzchak Scott-Thoennes, Orton, Yves, perl5-...@perl.org
Nicholas Clark <ni...@ccl4.org> wrote:

I agree with Nicholas and Tim.
Now, given that :
1/ there is code in production that mostly works and uses mistakenly this
construct (see the warnings found by Dave in perl's own test suite)
2/ there is code in production that use the sorta-static-variable trick
(my $foo if 0)
I favor a deprecation cycle. Warnings in 5.10, removal in 5.12.

Nicholas Clark

unread,
Feb 2, 2004, 3:06:22 PM2/2/04
to Tim Jenness, Rafael Garcia-Suarez, Tim Bunce, Yitzchak Scott-Thoennes, Orton, Yves, perl5-...@perl.org
On Mon, Feb 02, 2004 at 09:59:59AM -1000, Tim Jenness wrote:

> On Mon, 2 Feb 2004, Rafael Garcia-Suarez wrote:
>
> > I agree with Nicholas and Tim.
> > Now, given that :
> > 1/ there is code in production that mostly works and uses mistakenly this
> > construct (see the warnings found by Dave in perl's own test suite)
> > 2/ there is code in production that use the sorta-static-variable trick
> > (my $foo if 0)
> > I favor a deprecation cycle. Warnings in 5.10, removal in 5.12.
> >
>
> Isn't that likely to mean removal around the year 2006 or something at the
> current rate? That seems silly.

Silly in what sense? Yes, it will take a long time. But you seem to want
to trade correctness for speed.

I'm not even sure how dangerous this construction is.

> The next maintenance release could include a warning for the construct
> that was disabled by default (even with 'use warnings'). It would also be
> helpful to audit CPAN for the construct since that can be done in an
> automated fashion.

You are welcome to automate auditing CPAN. :-)

[I already have too much to do. I'd much prefer someone to automate testing
binary compatibility of CPAN modules between maintenance releases, given that
it's somewhere down my TODO and isn't getting any nearer the top]

If the default is disabled, even with use warnings, how are you proposing
that the warning should be enabled? I suspect I'm missing something obvious
about warnings.pm here - is there already a way to get "bonus" warnings?

Nicholas Clark

Tim Jenness

unread,
Feb 2, 2004, 2:59:59 PM2/2/04
to Rafael Garcia-Suarez, Nicholas Clark, Tim Bunce, Yitzchak Scott-Thoennes, Orton, Yves, perl5-...@perl.org
On Mon, 2 Feb 2004, Rafael Garcia-Suarez wrote:

> I agree with Nicholas and Tim.
> Now, given that :
> 1/ there is code in production that mostly works and uses mistakenly this
> construct (see the warnings found by Dave in perl's own test suite)
> 2/ there is code in production that use the sorta-static-variable trick
> (my $foo if 0)
> I favor a deprecation cycle. Warnings in 5.10, removal in 5.12.
>

Isn't that likely to mean removal around the year 2006 or something at the


current rate? That seems silly.

The next maintenance release could include a warning for the construct


that was disabled by default (even with 'use warnings'). It would also be
helpful to audit CPAN for the construct since that can be done in an
automated fashion.

--
Tim Jenness
JAC software
http://www.jach.hawaii.edu/~timj


Tim Jenness

unread,
Feb 2, 2004, 3:21:42 PM2/2/04
to Nicholas Clark, Rafael Garcia-Suarez, Tim Bunce, Yitzchak Scott-Thoennes, Orton, Yves, Perl 5 porters
On Mon, 2 Feb 2004, Nicholas Clark wrote:

> On Mon, Feb 02, 2004 at 09:59:59AM -1000, Tim Jenness wrote:
> > On Mon, 2 Feb 2004, Rafael Garcia-Suarez wrote:
> >
> > > I agree with Nicholas and Tim.
> > > Now, given that :
> > > 1/ there is code in production that mostly works and uses mistakenly this
> > > construct (see the warnings found by Dave in perl's own test suite)
> > > 2/ there is code in production that use the sorta-static-variable trick
> > > (my $foo if 0)
> > > I favor a deprecation cycle. Warnings in 5.10, removal in 5.12.
> > >
> >
> > Isn't that likely to mean removal around the year 2006 or something at the
> > current rate? That seems silly.
>
> Silly in what sense? Yes, it will take a long time. But you seem to want
> to trade correctness for speed.
>

Silly in the sense that it will take years (at the current release rate)
to remove usage of this construct to the point where removal will have
essentially no effect, especially if 5.12 never happens :-) What will
ponie be doing with this particular construct? If releases were coming out
once a year things would be different.

It seems to me (and I fully understand that I'm talking without having any
tuits to back me up) that more progress would be made by trying to make

my $x = 'blah' if $y;

do what people expect. Would that patch be suitable for release on the
maintenance branch (since it is a bug fix). Dealing with 'my $foo if 0'
will be harder since people are intentionally using a bug.

> I'm not even sure how dangerous this construction is.

This thread has been going on and off for a number of years now and
doesn't really get anywhere. Delaying the hit for 2 or 3 more years
doesn't help.

>
> > The next maintenance release could include a warning for the construct
> > that was disabled by default (even with 'use warnings'). It would also be
> > helpful to audit CPAN for the construct since that can be done in an
> > automated fashion.
>
> You are welcome to automate auditing CPAN. :-)
>

I know :-) I was hoping that Dave's magic script (that he ran on the test
suite) could be tweaked specifically to see how prevalent the construct
us.

> If the default is disabled, even with use warnings, how are you proposing
> that the warning should be enabled? I suspect I'm missing something obvious
> about warnings.pm here - is there already a way to get "bonus" warnings?

Hmm. I was thinking along the lines of

use warnings 'lexicalif';

but that is clearly bogus since why would anyone add that warning if they
are writing the code themselves (and therefore know about the problem).
I assume environment variables are bad as well. I was trying to think of a
way whereby I can have a runtime switch that will enable the warning
when I am auditing code but that will not generate a new warning for most
people (where unexpected warnings from released code are seen as a
bad thing). Forget I said anything!

Yitzchak Scott-Thoennes

unread,
Feb 2, 2004, 4:08:07 PM2/2/04
to perl5-...@perl.org

It's your call, and if you don't view it as a bugfix, there's no
reason you'd want to put it into maint, or even blead. But I think
the case for it being viewed as a bugfix is pretty strong.

Especially if the fix can be done for "my var = ... statement-modifier ..."
but leave "my var statement-modifier ..." alone.

Dave Mitchell

unread,
Feb 2, 2004, 7:56:07 PM2/2/04
to Tim Jenness, Nicholas Clark, Rafael Garcia-Suarez, Tim Bunce, Yitzchak Scott-Thoennes, Orton, Yves, Perl 5 porters
On Mon, Feb 02, 2004 at 10:21:42AM -1000, Tim Jenness wrote:
> On Mon, 2 Feb 2004, Nicholas Clark wrote:
>
> > On Mon, Feb 02, 2004 at 09:59:59AM -1000, Tim Jenness wrote:
> > > On Mon, 2 Feb 2004, Rafael Garcia-Suarez wrote:
> > >
> > > > I agree with Nicholas and Tim.
> > > > Now, given that :
> > > > 1/ there is code in production that mostly works and uses mistakenly this
> > > > construct (see the warnings found by Dave in perl's own test suite)
> > > > 2/ there is code in production that use the sorta-static-variable trick
> > > > (my $foo if 0)
> > > > I favor a deprecation cycle. Warnings in 5.10, removal in 5.12.
> > > >
> > >
> > > Isn't that likely to mean removal around the year 2006 or something at the
> > > current rate? That seems silly.
> >
> > Silly in what sense? Yes, it will take a long time. But you seem to want
> > to trade correctness for speed.
> >
>
> Silly in the sense that it will take years (at the current release rate)
> to remove usage of this construct to the point where removal will have
> essentially no effect, especially if 5.12 never happens :-) What will
> ponie be doing with this particular construct? If releases were coming out
> once a year things would be different.

For the record:

1. I don't think anything should go into maint: neither warning nor
bugfix.

2. I favour a deprecation cycle (even if it takes years), because we
have a combination of part of the user community being hit by an unexpected
bug and another part of the community explicity using the bug.
Also, this bug has been around since 5.000. Without deprecation we are
going break too many things.

3. I don't think it's possible to reliably distinguish between the two
cases based on stuff like whether it includes an assignment, and whether
the condition is C<if 0>.

4. I think if the warning appears in 5.10, it will be quite intrusive,
perhaps about the same level as when the defined(@array) warning
was introduced (which I seem to recall being a particualr pain at the time
as I had to manually patch various CPAN modules to get my programs to work
quietly).

> > You are welcome to automate auditing CPAN. :-)
> >
>
> I know :-) I was hoping that Dave's magic script (that he ran on the test
> suite) could be tweaked specifically to see how prevalent the construct
> us.

I don't have a magic script :-(. I just ran the test suite against
a perl opatched with the new warning, and looked at what warnings cropped
up and which tests suddenly started failing (ususally becuase the new
warning caused the expected output to fail).

--
Never do today what you can put off till tomorrow.

Dave Mitchell

unread,
Feb 2, 2004, 8:07:42 PM2/2/04
to Orton, Yves, Yitzchak Scott-Thoennes, Rafael Garcia-Suarez, perl5-...@perl.org
On Mon, Feb 02, 2004 at 11:07:22AM -0000, Orton, Yves wrote:
> > > if ( my $cond = ($foo && (my $val = foo()))) { print $val }
> > > =>
> > > ???
> >
> > Ouch.
>
> Umm can anybody explain why this is a problem? Because both $cond and $val
> are scoped to the if, there is no problem here. The only place that a
> problem comes up is in modifier form becuase in the modifer form the my
> exists at the scope level that encloses the if, not the scope level enclosed
> by the if.

The example above wasn't intended to b an example of the bug, but rather
an example of how tricky it will be for any patch handle code like the
above correctly - ie the stuff in Perl_peek() that rummages aroud in the
opcode tree looking for OP_AND or OP_OR near OP_PADSV etc needs to be
clever. Note that internally C<my $x if foo> is actually compiled as
C<foo && (my $x)>.

Also consider the following, which *does* exhibit the bug:

$cond = 0;
for (1..3) {
if ($cond && (my $x=1)) {
# ...
}
else {
$x++;
print $x, "\n";
}
}

outputs:

1
2
3


--
"Do not dabble in paradox, Edward, it puts you in danger of fortuitous
wit." -- Lady Croom - Arcadia

Yves Orton

unread,
Feb 3, 2004, 11:49:59 AM2/3/04
to Dave Mitchell, perl5-...@perl.org
> > Umm can anybody explain why this is a problem?
...

> The example above wasn't intended to b an example of the bug,
> but rather
> an example of how tricky it will be for any patch handle code like the
> above correctly - ie the stuff in Perl_peek() that rummages
> aroud in the
> opcode tree looking for OP_AND or OP_OR near OP_PADSV etc needs to be
> clever. Note that internally C<my $x if foo> is actually compiled as
> C<foo && (my $x)>.
>
> Also consider the following, which *does* exhibit the bug:
>
> $cond = 0;
> for (1..3) {
> if ($cond && (my $x=1)) {
> # ...
> }
> else {
> $x++;
> print $x, "\n";
> }
> }
>
> outputs:
>
> 1
> 2
> 3

Ok, I follow now. Thanks.

Yves

Abigail

unread,
Feb 7, 2004, 1:25:43 PM2/7/04
to Yitzchak Scott-Thoennes, Tim Bunce, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org


I don't think that information is readily available. But do you have any
information how often people write 'my $x = 1 if $foo' unintentionally?
That would be helpful information too.


Abigail

David Manura

unread,
Feb 7, 2004, 2:48:31 PM2/7/04
to Abigail, Yitzchak Scott-Thoennes, Tim Bunce, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org

Happened to me once:

http://www.experts-exchange.com/Programming/Programming_Languages/Perl/Q_20704972.html


I had converted one of my CGI programs to use FastCGI, and this introduced
random memory effects. Now I know better.

-davidm


Elizabeth Mattijsen

unread,
Feb 8, 2004, 7:57:49 AM2/8/04
to Abigail, Yitzchak Scott-Thoennes, Tim Bunce, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org

I was surprised by it a few years ago. And had to go through all of
my sources to correct as it was an idiom I had come to love and use
extensively. In the sense that I expected $x to be undef if the
condition was not true. And was caught by cases where it wasn't.


Liz

Yitzchak Scott-Thoennes

unread,
Feb 8, 2004, 1:38:46 PM2/8/04
to perl5-...@perl.org
On Sun, Feb 01, 2004 at 01:59:00AM +0000, Dave Mitchell <da...@fdisolutions.com> wrote:
> This patch threw up quite a lot of problems in the test suite, which is an
> indication that there's a *lot* of code out there about to get noisy.
> Here is a list of the major ones, along with sample snippets of code

Can you post your patch that you thought was too inefficient? I'd
like to see it.

Yitzchak Scott-Thoennes

unread,
Feb 8, 2004, 1:54:26 PM2/8/04
to Abigail, Tim Bunce, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org

Can't speak for "people", but I have accidentally done it perhaps half
a dozen times, and it's been reported as a bug a few times that I recall.

Dave Mitchell

unread,
Feb 8, 2004, 4:33:46 PM2/8/04
to Yitzchak Scott-Thoennes, perl5-...@perl.org

Here it is. Bear in mind that this is work-in-progress, and is nearly a
year old. It adds a new op that gets inserted at the start of blocks
that have mys, and does the initialisation stuff for all the lexicals in the
block that formerly would have been done by individual PAD*V ops.
It's slightly faster for blocks where where the PAD*V ops would have been
executed, and slower when they wouldn't have.

Dave.

--
Any [programming] language that doesn't occasionally surprise the
novice will pay for it by continually surprising the expert.
-- Larry Wall


# This is a patch for 18793.ORIG to update it to 18793
#
# To apply this patch:
# STEP 1: Chdir to the source directory.
# STEP 2: Run the 'applypatch' program with this patch file as input.
#
# If you do not have 'applypatch', it is part of the 'makepatch' package
# that you can fetch from the Comprehensive Perl Archive Network:
# http://www.perl.com/CPAN/authors/Johan_Vromans/makepatch-x.y.tar.gz
# In the above URL, 'x' should be 2 or higher.
#
# To apply this patch without the use of 'applypatch':
# STEP 1: Chdir to the source directory.
# STEP 2: Run the 'patch' program with this file as input.
#
#### End of Preamble ####

#### Patch data follows ####
diff -up '18793.ORIG/embed.fnc' '18793/embed.fnc'
Index: ./embed.fnc
--- ./embed.fnc Sat Mar 1 12:39:07 2003
+++ ./embed.fnc Wed Mar 5 22:55:00 2003
@@ -546,7 +546,7 @@ p |PADOFFSET|allocmy |char* name
pd |PADOFFSET|pad_findmy |char* name
p |OP* |oopsAV |OP* o
p |OP* |oopsHV |OP* o
-pd |void |pad_leavemy
+pd |SV* |pad_leavemy
Apd |SV* |pad_sv |PADOFFSET po
pd |void |pad_free |PADOFFSET po
pd |void |pad_reset
diff -up '18793.ORIG/ext/Opcode/Opcode.pm' '18793/ext/Opcode/Opcode.pm'
Index: ./ext/Opcode/Opcode.pm
--- ./ext/Opcode/Opcode.pm Sat Mar 1 23:10:09 2003
+++ ./ext/Opcode/Opcode.pm Sat Mar 1 23:10:30 2003
@@ -393,7 +393,7 @@ These are a hotchpotch of opcodes still

gvsv gv gelem

- padsv padav padhv padany
+ padsv padav padhv padany intromy

rv2gv refgen srefgen ref

diff -up '18793.ORIG/op.c' '18793/op.c'
Index: ./op.c
--- ./op.c Sat Mar 1 12:38:51 2003
+++ ./op.c Fri Mar 7 00:25:49 2003
@@ -1752,13 +1752,18 @@ Perl_block_end(pTHX_ I32 floor, OP *seq)
{
int needblockscope = PL_hints & HINT_BLOCK_SCOPE;
OP* retval = scalarseq(seq);
+ SV* targlist;
/* If there were syntax errors, don't try to close a block */
if (PL_yynerrs) return retval;
LEAVE_SCOPE(floor);
PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
if (needblockscope)
PL_hints |= HINT_BLOCK_SCOPE; /* propagate out */
- pad_leavemy();
+ targlist = pad_leavemy();
+ if (targlist) {
+ OP* o = newSVOP(OP_INTROMY, 0, targlist);
+ retval = prepend_elem(OP_LINESEQ, o, retval);
+ }
return retval;
}

@@ -6063,6 +6068,26 @@ Perl_peep(pTHX_ register OP *o)
o->op_seq = PL_op_seqmax++;
break;

+ case OP_PADSV:
+ case OP_PADAV:
+ case OP_PADHV:
+ /* XXX what about PADANY ??? */
+
+ /* remove 'my' in void context */
+ /* XXX but need to keep for deparse etc ??? */
+
+ if (o->op_flags & OPf_MOD
+ && (o->op_flags & OPf_WANT) == OPf_WANT_VOID
+ && o->op_private & OPpLVAL_INTRO)
+ {
+ /* XXX just null or remove from chain altogether ?? */
+ DEBUG_Xv(PerlIO_printf(Perl_debug_log,
+ "XXX removing pad?v, ix=%lu\n", (unsigned long) o->op_targ));
+ op_null(o);
+ }
+ o->op_seq = PL_op_seqmax++;
+ break;
+
case OP_CONST:
if (cSVOPo->op_private & OPpCONST_STRICT)
no_bareword_allowed(o);
diff -up '18793.ORIG/opcode.h' '18793/opcode.h'
Index: ./opcode.h
--- ./opcode.h Sat Mar 1 12:38:51 2003
+++ ./opcode.h Wed Mar 5 23:23:23 2003
@@ -382,6 +382,7 @@ EXT char *PL_op_name[] = {
"method_named",
"dor",
"dorassign",
+ "intromy",
"custom",
};
#endif
@@ -743,6 +744,7 @@ EXT char *PL_op_desc[] = {
"method with known name",
"defined or (//)",
"defined or assignment (//=)",
+ "initialise my vars",
"unknown custom operator",
};
#endif
@@ -1109,6 +1111,7 @@ EXT OP * (CPERLscope(*PL_ppaddr)[])(pTHX
MEMBER_TO_FPTR(Perl_pp_method_named),
MEMBER_TO_FPTR(Perl_pp_dor),
MEMBER_TO_FPTR(Perl_pp_dorassign),
+ MEMBER_TO_FPTR(Perl_pp_intromy),
};
#endif

@@ -1469,6 +1472,7 @@ EXT OP * (CPERLscope(*PL_check)[]) (pTHX
MEMBER_TO_FPTR(Perl_ck_null), /* method_named */
MEMBER_TO_FPTR(Perl_ck_null), /* dor */
MEMBER_TO_FPTR(Perl_ck_null), /* dorassign */
+ MEMBER_TO_FPTR(Perl_ck_null), /* intromy */
MEMBER_TO_FPTR(Perl_ck_null), /* custom */
};
#endif
@@ -1830,6 +1834,7 @@ EXT U32 PL_opargs[] = {
0x00000c40, /* method_named */
0x00000600, /* dor */
0x00000604, /* dorassign */
+ 0x00001000, /* intromy */
0x00000000, /* custom */
};
#endif
diff -up '18793.ORIG/opcode.pl' '18793/opcode.pl'
Index: ./opcode.pl
--- ./opcode.pl Sat Mar 1 12:38:51 2003
+++ ./opcode.pl Wed Mar 5 23:23:16 2003
@@ -1,4 +1,19 @@
#!/usr/bin/perl
+#
+# opcode.pl
+#
+# Copyright (c) 1994-2003, Larry Wall
+#
+# You may distribute under the terms of either the GNU General Public
+# License or the Artistic License, as specified in the README file.
+#
+# This script generates the following dervided files from the table
+# at the end of this file:
+# opcode.h
+# opnames.h
+# pp_proto.h
+# pp.sym
+
BEGIN {
# Get function prototypes
require 'regen.pl';
@@ -923,6 +938,8 @@ method_named method with known name ck_n
dor defined or (//) ck_null |
dorassign defined or assignment (//=) ck_null s|

+intromy initialise my vars ck_null "
+
# Add new ops before this, the custom operator.

custom unknown custom operator ck_null 0
diff -up '18793.ORIG/opnames.h' '18793/opnames.h'
Index: ./opnames.h
--- ./opnames.h Sat Mar 1 12:38:51 2003
+++ ./opnames.h Wed Mar 5 23:23:23 2003
@@ -366,11 +366,12 @@ typedef enum opcode {
OP_METHOD_NAMED,/* 350 */
OP_DOR, /* 351 */
OP_DORASSIGN, /* 352 */
- OP_CUSTOM, /* 353 */
+ OP_INTROMY, /* 353 */
+ OP_CUSTOM, /* 354 */
OP_max
} opcode;

-#define MAXO 354
+#define MAXO 355
#define OP_phoney_INPUT_ONLY -1
#define OP_phoney_OUTPUT_ONLY -2

diff -up '18793.ORIG/pad.c' '18793/pad.c'
Index: ./pad.c
--- ./pad.c Sat Mar 1 12:39:07 2003
+++ ./pad.c Thu Mar 6 00:52:46 2003
@@ -890,16 +890,20 @@ Perl_intro_my(pTHX)

Cleanup at end of scope during compilation: set the max seq number for
lexicals in this scope and warn of any lexicals that never got introduced.
+If any lexicals were in scope, return an SV whose PVX member is cast to
+an array of U32s containg the indices of those lexicals; otherwise return
+null.

=cut
*/

-void
+SV *
Perl_pad_leavemy(pTHX)
{
I32 off;
SV **svp = AvARRAY(PL_comppad_name);
SV *sv;
+ SV *targs = Nullsv;

PL_pad_reset_pending = FALSE;

@@ -923,11 +927,21 @@ Perl_pad_leavemy(pTHX)
(long)off, SvPVX(sv),
(unsigned long)I_32(SvNVX(sv)), (unsigned long)SvIVX(sv))
);
+ if (!targs)
+ targs = NEWSV(1, 4 * sizeof(U32));
+ else if (SvCUR(targs) >= SvLEN(targs))
+ SvGROW(targs, SvLEN(targs)*2);
+ ((U32*)SvPVX(targs))[ SvCUR(targs) / sizeof(U32) ] = off;
+ DEBUG_Xv(PerlIO_printf(Perl_debug_log,
+ "Pad XXX leavemy: sv=0x%x p=0x%x\n", targs,
+ &( ((U32*)SvPVX(targs))[ SvCUR(targs) * sizeof(U32) ])));
+ SvCUR(targs) += sizeof(U32);
}
}
PL_cop_seqmax++;
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
"Pad leavemy: seq = %ld\n", (long)PL_cop_seqmax));
+ return targs;
}


diff -up '18793.ORIG/pp.c' '18793/pp.c'
Index: ./pp.c
--- ./pp.c Sat Mar 1 12:38:52 2003
+++ ./pp.c Sun Mar 2 13:43:29 2003
@@ -48,8 +48,6 @@ PP(pp_padav)
{
dSP; dTARGET;
I32 gimme;
- if (PL_op->op_private & OPpLVAL_INTRO)
- SAVECLEARSV(PAD_SVl(PL_op->op_targ));
EXTEND(SP, 1);
if (PL_op->op_flags & OPf_REF) {
PUSHs(TARG);
@@ -91,8 +89,6 @@ PP(pp_padhv)
I32 gimme;

XPUSHs(TARG);
- if (PL_op->op_private & OPpLVAL_INTRO)
- SAVECLEARSV(PAD_SVl(PL_op->op_targ));
if (PL_op->op_flags & OPf_REF)
RETURN;
else if (LVRET) {
diff -up '18793.ORIG/pp.sym' '18793/pp.sym'
Index: ./pp.sym
--- ./pp.sym Sat Mar 1 12:38:52 2003
+++ ./pp.sym Wed Mar 5 23:23:23 2003
@@ -392,3 +392,4 @@ Perl_pp_setstate
Perl_pp_method_named
Perl_pp_dor
Perl_pp_dorassign
+Perl_pp_intromy
diff -up '18793.ORIG/pp_hot.c' '18793/pp_hot.c'
Index: ./pp_hot.c
--- ./pp_hot.c Sat Mar 1 12:38:52 2003
+++ ./pp_hot.c Fri Mar 7 01:58:51 2003
@@ -37,6 +37,24 @@ PP(pp_nextstate)
return NORMAL;
}

+/* use the array of targs stored in the PVX field of the SV to
+ * introduce lexes */
+
+PP(pp_intromy)
+{
+ SV *sv = cSVOP->op_sv;
+ U32 *p = (U32*)(SvPVX(sv));
+ U32 i = SvCUR(sv) / sizeof(U32);
+
+ SAVECLEAR_PADSVS(sv);
+ while (i--) {
+ DEBUG_Xv(PerlIO_printf(Perl_debug_log, "Pad %"UVuf" stale off\n", *p));
+ SvPADSTALE_off(PAD_SVl(*p++));
+ }
+
+ return NORMAL;
+}
+
PP(pp_gvsv)
{
dSP;
@@ -194,14 +212,10 @@ PP(pp_padsv)
{
dSP; dTARGET;
XPUSHs(TARG);
- if (PL_op->op_flags & OPf_MOD) {
- if (PL_op->op_private & OPpLVAL_INTRO)
- SAVECLEARSV(PAD_SVl(PL_op->op_targ));
- else if (PL_op->op_private & OPpDEREF) {
- PUTBACK;
- vivify_ref(PAD_SVl(PL_op->op_targ), PL_op->op_private & OPpDEREF);
- SPAGAIN;
- }
+ if (PL_op->op_private & OPpDEREF) {
+ PUTBACK;
+ vivify_ref(PAD_SVl(PL_op->op_targ), PL_op->op_private & OPpDEREF);
+ SPAGAIN;
}
RETURN;
}
diff -up '18793.ORIG/scope.c' '18793/scope.c'
Index: ./scope.c
--- ./scope.c Sat Mar 1 12:38:52 2003
+++ ./scope.c Fri Mar 7 02:00:33 2003
@@ -541,14 +541,16 @@ Perl_save_freepv(pTHX_ char *pv)
SSPUSHINT(SAVEt_FREEPV);
}

+/* XXX obsolete */
void
Perl_save_clearsv(pTHX_ SV **svp)
{
- ASSERT_CURPAD_ACTIVE("save_clearsv");
- SSCHECK(2);
- SSPUSHLONG((long)(svp-PL_curpad));
- SSPUSHINT(SAVEt_CLEARSV);
- SvPADSTALE_off(*svp); /* mark lexical as active */
+ assert(0 && "XXX obsolete save_clearsv");
+ /* XXX ASSERT_CURPAD_ACTIVE("save_clearsv"); */
+ /* XXX SSCHECK(2); */
+ /* XXX SSPUSHLONG((long)(svp-PL_curpad)); */
+ /* XXX SSPUSHINT(SAVEt_CLEARSV); */
+ /* XXX SvPADSTALE_off(*svp); */
}

void
@@ -872,66 +874,73 @@ Perl_leave_scope(pTHX_ I32 base)
ptr = SSPOPPTR;
Safefree((char*)ptr);
break;
- case SAVEt_CLEARSV:
- ptr = (void*)&PL_curpad[SSPOPLONG];
- sv = *(SV**)ptr;
-
- DEBUG_Xv(PerlIO_printf(Perl_debug_log,
- "Pad 0x%"UVxf"[0x%"UVxf"] clearsv: %ld sv=0x%"UVxf"<%"IVdf"> %s\n",
- PTR2UV(PL_comppad), PTR2UV(PL_curpad),
- (long)((SV **)ptr-PL_curpad), PTR2UV(sv), (IV)SvREFCNT(sv),
- (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) ? "clear" : "abandon"
- ));
-
- /* Can clear pad variable in place? */
- if (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) {
- /*
- * if a my variable that was made readonly is going out of
- * scope, we want to remove the readonlyness so that it can
- * go out of scope quietly
- */
- if (SvPADMY(sv) && !SvFAKE(sv))
- SvREADONLY_off(sv);
-
- if (SvTHINKFIRST(sv))
- sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF);
- if (SvMAGICAL(sv))
- mg_free(sv);
-
- switch (SvTYPE(sv)) {
- case SVt_NULL:
- break;
- case SVt_PVAV:
- av_clear((AV*)sv);
- break;
- case SVt_PVHV:
- hv_clear((HV*)sv);
- break;
- case SVt_PVCV:
- Perl_croak(aTHX_ "panic: leave_scope pad code");
- case SVt_RV:
- case SVt_IV:
- case SVt_NV:
- (void)SvOK_off(sv);
- break;
- default:
- (void)SvOK_off(sv);
- (void)SvOOK_off(sv);
- break;
+ case SAVEt_CLEAR_PADSVS:
+ sv = (SV*)SSPOPPTR;
+ for ( i = SvCUR(sv) / sizeof(U32), str = SvPVX(sv);
+ i-- > 0;
+ ((U32*)str)++
+ ) {
+ ptr = &(PAD_SVl(*(U32*)str));
+ sv = *(SV**)ptr;
+
+ DEBUG_Xv(PerlIO_printf(Perl_debug_log,
+ "Pad 0x%"UVxf"[0x%"UVxf"] clearsv: %ld sv=0x%"UVxf"<%"IVdf"> %s\n",
+ PTR2UV(PL_comppad), PTR2UV(PL_curpad),
+ (long) *( (U32* str)),
+ PTR2UV(sv), (IV)SvREFCNT(sv),
+ (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) ? "clear" : "abandon"
+ ));
+
+ /* Can clear pad variable in place? */
+ if (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) {
+ /*
+ * if a my variable that was made readonly is going out of
+ * scope, we want to remove the readonlyness so that it can
+ * go out of scope quietly
+ */
+ if (SvPADMY(sv) && !SvFAKE(sv))
+ SvREADONLY_off(sv);
+
+ if (SvTHINKFIRST(sv))
+ sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF);
+ if (SvMAGICAL(sv))
+ mg_free(sv);
+
+ switch (SvTYPE(sv)) {
+ case SVt_NULL:
+ break;
+ case SVt_PVAV:
+ av_clear((AV*)sv);
+ break;
+ case SVt_PVHV:
+ hv_clear((HV*)sv);
+ break;
+ case SVt_PVCV:
+ Perl_croak(aTHX_ "panic: leave_scope pad code");
+ case SVt_RV:
+ case SVt_IV:
+ case SVt_NV:
+ (void)SvOK_off(sv);
+ break;
+ default:
+ (void)SvOK_off(sv);
+ (void)SvOOK_off(sv);
+ break;
+ }
+ SvPADSTALE_on(sv); /* mark as no longer live */
}
- SvPADSTALE_on(sv); /* mark as no longer live */
- }
- else { /* Someone has a claim on this, so abandon it. */
- U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP);
- switch (SvTYPE(sv)) { /* Console ourselves with a new value */
- case SVt_PVAV: *(SV**)ptr = (SV*)newAV(); break;
- case SVt_PVHV: *(SV**)ptr = (SV*)newHV(); break;
- default: *(SV**)ptr = NEWSV(0,0); break;
+ else { /* Someone has a claim on this, so abandon it. */
+ U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP);
+ switch (SvTYPE(sv)) { /* Console ourselves with a new value */
+ case SVt_PVAV: *(SV**)ptr = (SV*)newAV(); break;
+ case SVt_PVHV: *(SV**)ptr = (SV*)newHV(); break;
+ default: *(SV**)ptr = NEWSV(0,0); break;
+ }
+ SvREFCNT_dec(sv); /* Cast current value to the winds. */
+ /* preserve pad nature, but also mark as not live
+ * for any closure capturing */
+ SvFLAGS(*(SV**)ptr) |= padflags & SVs_PADSTALE;
}
- SvREFCNT_dec(sv); /* Cast current value to the winds. */
- /* preserve pad nature, but also mark as not live
- * for any closure capturing */
- SvFLAGS(*(SV**)ptr) |= padflags & SVs_PADSTALE;
}
break;
case SAVEt_DELETE:
diff -up '18793.ORIG/scope.h' '18793/scope.h'
Index: ./scope.h
--- ./scope.h Sat Mar 1 12:38:52 2003
+++ ./scope.h Fri Mar 7 01:29:28 2003
@@ -25,7 +25,7 @@
#define SAVEt_FREESV 15
#define SAVEt_FREEOP 16
#define SAVEt_FREEPV 17
-#define SAVEt_CLEARSV 18
+#define SAVEt_CLEAR_PADSVS 18
#define SAVEt_DELETE 19
#define SAVEt_DESTRUCTOR 20
#define SAVEt_REGCONTEXT 21
@@ -128,7 +128,15 @@ Closing bracket on a callback. See C<EN
#define SAVEMORTALIZESV(s) save_mortalizesv((SV*)(s))
#define SAVEFREEOP(o) save_freeop(SOFT_CAST(OP*)(o))
#define SAVEFREEPV(p) save_freepv(SOFT_CAST(char*)(p))
-#define SAVECLEARSV(sv) save_clearsv(SOFT_CAST(SV**)&(sv))
+
+#define SAVECLEAR_PADSVS(sv) \
+ STMT_START { \
+ SSCHECK(2); \
+ SSPUSHPTR(sv); \
+ SSPUSHINT(SAVEt_CLEAR_PADSVS); \
+ } STMT_END
+
+
#define SAVEGENERICSV(s) save_generic_svref((SV**)&(s))
#define SAVEGENERICPV(s) save_generic_pvref((char**)&(s))
#define SAVESHAREDPV(s) save_shared_pvref((char**)&(s))
#### End of Patch data ####

#### ApplyPatch data follows ####
# Data version : 1.0
# Date generated : Fri Mar 7 02:15:40 2003
# Generated by : makepatch 2.00_05
# Recurse directories : Yes
# Excluded files : keywords\.h|warnings\.h|regnodes\.h|perlapi\.c|perlapi\.h|global\.sym|embedvar\.h|embed\.h|pod\/perlapi\.pod|pod\/perlintern\.pod|proto\.h
# v 'patchlevel.h' 4454 1046525176 33188
# p 'embed.fnc' 50342 1046904900 0100644
# p 'ext/Opcode/Opcode.pm' 15247 1046560230 0100644
# p 'op.c' 156235 1046996749 0100644
# p 'opcode.h' 46868 1046906603 0100664
# p 'opcode.pl' 24875 1046906596 0100755
# p 'opnames.h' 9290 1046906603 0100664
# p 'pad.c' 37905 1046911966 0100644
# p 'pp.c' 101911 1046612609 0100644
# p 'pp.sym' 5931 1046906603 0100664
# p 'pp_hot.c' 70989 1047002331 0100644
# p 'scope.c' 27093 1047002433 0100644
# p 'scope.h' 12973 1047000568 0100644
#### End of ApplyPatch data ####

#### End of Patch kit [created: Fri Mar 7 02:15:40 2003] ####
#### Patch checksum: 513 15026 28323 ####
#### Checksum: 531 15704 18513 ####

Abigail

unread,
Feb 9, 2004, 5:53:28 PM2/9/04
to Yitzchak Scott-Thoennes, Tim Bunce, Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org


Just for the record, I've never written 'my $foo = blah if whatever;'
by accident, and I've never written it on purpose in any serious code.


Abigail

H.Merijn Brand

unread,
Feb 9, 2004, 5:59:17 PM2/9/04
to Abigail, Perl 5 Porters

For the same record. I've never written it at all, but I think that I can
count the times that I used statement modifiers like this on a single hand.

I prefer

m/regex/ and action ();

over

action () if m/regex/;

just personal preference


If the above also influences the behaviour of

my ($foo) = (m/blah(.*)baz/) and $blo = $foo;

then I've probably used it too

--
H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/)
using perl-5.6.1, 5.8.0, & 5.9.x, and 806 on HP-UX 10.20 & 11.00, 11i,
AIX 4.3, SuSE 8.2, and Win2k. http://www.cmve.net/~merijn/
http://archives.develooper.com/daily...@perl.org/ per...@perl.org
send smoke reports to: smokers...@perl.org, QA: http://qa.perl.org

H.Merijn Brand

unread,
Feb 9, 2004, 6:08:29 PM2/9/04
to Rafael Garcia-Suarez, Perl 5 Porters
On Tue 10 Feb 2004 00:06, Rafael Garcia-Suarez <rgarci...@free.fr> wrote:

> H.Merijn Brand wrote:
> > If the above also influences the behaviour of
> >
> > my ($foo) = (m/blah(.*)baz/) and $blo = $foo;
> >
> > then I've probably used it too
>
> It's more equivalent to
>
> $condition and my $foo = $bar;
>
> (But the problem is maybe a little more clear with this last writing
> than with the C<if> form.)

OK, then I'm safe.

Which also means that I have no opinion about whether to depricate it or not
or whether it is useful or not. Personally I don't like, and don't use this
construct. The only time I will be bitten by the (un)wanted behaviour is when
I have to take over maintainance of scripts that use it and I rewrite it to
contructs that I like. Equally dangerous though.

Rafael Garcia-Suarez

unread,
Feb 9, 2004, 6:06:45 PM2/9/04
to H.Merijn Brand, Abigail, Perl 5 Porters
H.Merijn Brand wrote:
> If the above also influences the behaviour of
>
> my ($foo) = (m/blah(.*)baz/) and $blo = $foo;
>
> then I've probably used it too

It's more equivalent to

0 new messages