I could find nothing in the Perl documentation on the lifetime of my
variables. The scope of the name is lexical, but what about the value?
Specifically, if a my variable is declared in a block, does it retain
its value from the previous time you entered the block? If a my
variable is declared in a while statement, does it retain its value
across iterations?
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
> I could find nothing in the Perl documentation on the lifetime of my
> variables. The scope of the name is lexical, but what about the value?
> Specifically, if a my variable is declared in a block, does it retain
> its value from the previous time you entered the block?
Basically you get a new variable each time you reach the my statement.
If you want to have a variable that keeps the vallue between each time
you enter the block, you should look at state variables. See the perlsub
manual page, the section titled "Persistent Private Variables".
> I could find nothing in the Perl documentation on the lifetime of my
> variables. The scope of the name is lexical, but what about the value?
> Specifically, if a my variable is declared in a block, does it retain
> its value from the previous time you entered the block? If a my
> variable is declared in a while statement, does it retain its value
> across iterations?
No in both cases. If you take a reference and pass it outside the block
you can make the variable outlast the name, but next time you enter the
block the name will get a fresh (undefined) variable attached to it. (As
an optimisation, if the variable has no outstanding references at the
end of the block perl will clear it out and reuse the same memory next
time the block is entered, but this only applies in situations where it
cannot make any difference to the semantics.)
For example
use 5.010;
my $y;
for (1..3) {
say "ITERATION: $_";
my $x;
say "New lexical: [$x] " . \$x;
$x = $_;
say "After assignment: [$x]";
$_ == 2 and $y = \$x;
}
say "Captured lexical: [$$y] $y";
gives
ITERATION: 1
New lexical: [] SCALAR(0x822608)
After assignment: [1]
ITERATION: 2
New lexical: [] SCALAR(0x822608)
After assignment: [2]
ITERATION: 3
New lexical: [] SCALAR(0x8195d8)
After assignment: [3]
Captured lexical: [2] SCALAR(0x822608)
so the second iteration reused the same memory as the first, but cleared
it out so it looked like a fresh variable, whereas the third had to
allocate a new variable since the old one was still referenced by $y. In
both cases the variable started the loop containing undef.
If you want the behaviour you describe, you can get it from perl 5.10
with 'state' variables. A 'state' variable is a lexical just like 'my',
but there is only ever one instance of it which is shared by all entries
into that block. Any initialisation is performed exactly once, the first
time that statement is executed. (This is nearly exactly like static
variables in C, if you know C.)
Since 'state' was a new keyword in 5.10, it must be enabled (just like
'say') with the 'feature' pragma. The simplest way to do this is to say
use 5.010;
which implicitly performs
use feature ":5.10";
which is equivalent to
use feature qw/switch state say/;
It currently isn't possible to initialise an array or hash state
variable; I can't remember why, but there was a nearly good reason :).
Assigning a ref to a scalar state variable works perfectly well, so
that's the obvious workaround.
In <gnq709-7ff2....@anubis.morrow.me.uk>, on 02/07/2012
at 02:57 PM, Ben Morrow <b...@morrow.me.uk> said:
>No in both cases. If you take a reference and pass it outside the
>block you can make the variable outlast the name, but next time you
>enter the block the name will get a fresh (undefined) variable
>attached to it.
That's the behavior I wanted, but somehow it's getting the value from
the previous iteration. I'd post the full code, but it's 1723 lines
long.
>If you want the behaviour you describe,
Superficially it looks as though I'm getting that behavior, and I'm
trying to figure out why :-(
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
In <87lioeu4pt....@vps1.hacking.dk>, on 02/07/2012
at 02:56 PM, Peter Makholm <pe...@makholm.net> said:
>If you want to have a variable that keeps the vallue between each
>time you enter the block, you should look at state variables.
I've got the opposite problem; I've got a variable that is supposed to
be undefrined at the beginning of each iteration and it's picking up a
value from a previous iteration. The program is rather large, but the
basic structure is
if ($prevHELO) {
msg("\t\$prevHELO=$prevHELO\n");
msg("\t\$prevSrc=$prevSrc\n");
unless (uc $by1 eq $prevHELO or
"\U$by2.$by1" eq $prevHELO or
uc $by1 eq $prevSrc or
"\U$by2.$by1" eq $prevSrc) {
$prevHELO=$HELO;
msg("\t\$prevHELO after mismatch set to $prevHELO\n");
return undef();
}
if ($prevBogus) {
msg("\tPrevious Received field was bad; skipping $From\n");
return undef();
}
} elsif ($lookup && $MARF) {
$host_info{$IP}{MARF}=1 if $IP;
$host_info{$rDNS}{MARF}=1 if $rDNS;
}
$prevHELO=$HELO;
msg("\t\$prevHELO set to $prevHELO\n");
...
}
...
}
The intention is for each mailfile from the parameter list to start
out with a clean value of $prevHELO, but if I specify two files to the
script then the second file is processed with the residual value of
$prevHELO from the first file.
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
It dives a bit into the gory parts of perl, but I think this is you
problem.
'sub doReceived' generates a function at compile time, refering to the
variable existing at compile time. Therefore it is not using the
variable initialized by the my statement in the outer loop.
Have you enabled 'use warnings' and 'use strict'?
I would think that at least one of them would catch this, but I'm not
quite sure which (as I'm not quite convinced about how perl actually
works for this example) and if the message is any meaningful.
> It dives a bit into the gory parts of perl, but I think this is you
> problem.
> 'sub doReceived' generates a function at compile time, refering to the
> variable existing at compile time. Therefore it is not using the
> variable initialized by the my statement in the outer loop.
The my-variable is exists in the lexical scope it is defined in and
since the subroutine is not defined inside the same lexical scope, it
uses the variable $prevHELO of the current package. Which will of
course keep its value unless the value is changed.
Perl code which achieves what was probably intended:
----------------
our $prevHELO;
while (<>) {
local $prevHELO;
print_it();
}
sub print_it()
{
print("|$prevHELO|");
$prevHELO = 'bla';
> >> mailfile: while (my $mailfile=shift) {
> >> my $prevHELO;
> >> foreach (@Received[$ReceivedIx..$#Received]) {
> >> sub doReceived {
> >> if ($prevHELO) {
> > It dives a bit into the gory parts of perl, but I think this is you
> > problem.
> > 'sub doReceived' generates a function at compile time, refering to the
> > variable existing at compile time. Therefore it is not using the
> > variable initialized by the my statement in the outer loop.
> The my-variable is exists in the lexical scope it is defined in and
> since the subroutine is not defined inside the same lexical scope, it
> uses the variable $prevHELO of the current package. Which will of
> course keep its value unless the value is changed.
There are no package variables in the code Shmuel posted. The subroutine
is defined within the lexical scope of $prevHELO, otherwise it would
have given a strictures error.
> It dives a bit into the gory parts of perl, but I think this is you
> problem.
> 'sub doReceived' generates a function at compile time, refering to the
> variable existing at compile time. Therefore it is not using the
> variable initialized by the my statement in the outer loop.
Yup. A named sub should never be defined inside a block which will
execute more than once. If you want a sub which will close over the
value of $prevHELO from outside, you can use an anonymous sub:
mailfile: while (...) {
my $prevHELO;
my $doReceived = sub { ... };
foreach (...) {
$doReceived->(...);
}
}
Otherwise you'll need to define doReceived outside the loop and pass
$prevHELO in as a parameter.
> Have you enabled 'use warnings' and 'use strict'?
> I would think that at least one of them would catch this, but I'm not
> quite sure which (as I'm not quite convinced about how perl actually
> works for this example) and if the message is any meaningful.
The relevant warning is 'Variable $x will not stay shared'. However, the
machinery which produces that warning is partially heuristic, and it
misses some cases. This is unfortunately one of them.
(In detail: because the while loop is at the top level of the program,
and because perl doesn't quite treat blocks which aren't subs as true
blocks, it doesn't realise that $prevHELO is declared in a section of
code which might run more than once.)
In <87ehu6tobv....@vps1.hacking.dk>, on 02/07/2012
at 08:50 PM, Peter Makholm <pe...@makholm.net> said:
>Have you enabled 'use warnings' and 'use strict'?
Only use strict
>'sub doReceived' generates a function at compile time, refering to
>the variable existing at compile time. Therefore it is not using the
>variable initialized by the my statement in the outer loop.
Even though it is contained in the loop?
I get the same residual value with
mailfile: while (my $mailfile=shift) {
...
foreach (@Received[$ReceivedIx..$#Received]) {
my $prevHELO;
sub doReceived {
my ($From, $HELO, $rDNS, $IP, $by1, $by2) = @_;
msg("\ndoReceived parameters:\n");
msg("\n\$From=$From\n");
msg("\n\$HELO=$HELO\n");
msg("\n\$rDNS=$rDNS\n");
msg("\n\$IP =$IP \n");
msg("\n\$by1 =$by1 \n");
msg("\n\$by2 =$by2 \n");
$HELO = uc $HELO;
$rDNS = uc $rDNS;
$IP = "[$IP]" unless $IP =~ /\[/;
my $goodHELO;
if ($MAIN::prevHELO) {
msg("\t\$prevHELO=$MAIN::prevHELO\n");
msg("\t\$prevSrc=$prevSrc\n");
unless (uc $by1 eq $MAIN::prevHELO or
"\U$by2.$by1" eq $MAIN::prevHELO or
uc $by1 eq $prevSrc or
"\U$by2.$by1" eq $prevSrc) {
$MAIN::prevHELO=$HELO;
msg("\t\$prevHELO after mismatch set to $MAIN::prevHELO\n");
return undef();
}
if ($prevBogus) {
msg("\tPrevious Received field was bad; skipping $From\n");
return undef();
}
} elsif ($lookup && $MARF) {
$host_info{$IP}{MARF}=1 if $IP;
$host_info{$rDNS}{MARF}=1 if $rDNS;
}
$MAIN::prevHELO=$HELO;
msg("\t\$prevHELO set to $MAIN::prevHELO\n");
$prevSrc=$rDNS;
$prevIP=$IP;
# Check for loopback or RFC 1918 source IP.
my $skipIP = localIP(inet_aton substr $IP, 1, -1);
$goodIP=$IP unless $skipIP;
$host_info{$IP}{skipIP}=$skipIP;
msg("\nDumper(\$skipIP)\n");
msg(Dumper($skipIP));
msg("\nDumper(\$goodIP)\n");
msg(Dumper($goodIP));
if ($skipIP) {
push @{$host_info{$goodIP}{msg}},
": the spam was routed via $skipIP IP $IP with HELO
$HELO\n";
return 1;
};
# Set up HELO and sent-from processing.
$_ = $HELO;
my $sent;
$sent = 'the spam was sent from';
$sent .= ' or relayed by' if /(?:$relayedDom)$/;
msg("\nTest HELO $HELO for IP or TLD\n");
# Don't process HELO/EHLO if it's TLD;
# validity check if it's IP address.
my $rDNSeff = $rDNS;
$rDNSeff =~ s/^\[$RE{net}{IPv4}\]$//o;
$rDNSeff =~ s/^$RE{net}{IPv4}$//o;
$rDNSeff =~ s/^[\w-]+$//o;
msg("\n\$rDNS=$rDNS, \$rDNSeff=$rDNSeff\n");
if (/^\[$RE{net}{IPv4}\]$/ || /^$RE{net}{IPv4}$/) {
msg("\nHELO $HELO is IP address.\n");
if ($IP eq $_) {
msg("\nHELO $HELO is matching and compliant IP address.\n");
$goodHELO = 1;
} elsif ($IP eq "[$_]") {
msg("\nHELO $HELO is matching but noncompliant IP
address.\n");
} else {
msg("\nHELO $HELO is bogus IP address.\n");
$prevBogus=1;
}
$host_info{$IP}{SMTP}{$rDNSeff.$IP} = $rDNSeff||$IP;
} elsif (/^[\w-]+$/ | $_ eq '.') {
msg("\nHELO $HELO not valid domain.\n");
$host_info{$IP}{SMTP}{$rDNSeff.$IP} = $rDNSeff||$IP;
} elsif ($rDNS eq $HELO) {
msg("\nrDNS $rDNS equal HELO $HELO\n");
$host_info{$IP}{SMTP}{$From} = $rDNS;
} else {
$goodHELO = 1;
$host_info{$HELO}{isHELO} = 1;
$host_info{$HELO}{SMTP}{$From} = $IP;
push @{$host_info{$HELO}{msg}},
": $sent $From\n";
$host_info{$IP}{SMTP}{$From} = $rDNS;
}
$host_info{$IP}{isIP} = 1;
msg("\n\$From from $From\n");
if ($goodHELO) {
push @{$host_info{$IP}{msg}},
": $sent $From in your IP space.\n";
} else {
push @{$host_info{$IP}{msg}},
": $sent $rDNSeff $IP in your IP space.\n";
}
if ($rDNS =~ /$notTLDpat/) {
$host_info{$rDNS}{SrcIP} = $IP;
$host_info{$rDNS}{SMTP}{$From} = $IP;
push @{$host_info{$rDNS}{msg}},
": $sent $From\n";
}
return 1;
}
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
> In <87ehu6tobv....@vps1.hacking.dk>, on 02/07/2012
> at 08:50 PM, Peter Makholm <pe...@makholm.net> said:
> >'sub doReceived' generates a function at compile time, refering to
> >the variable existing at compile time. Therefore it is not using the
> >variable initialized by the my statement in the outer loop.
> Even though it is contained in the loop?
Yes. This is a necessary consequence of the fact that named subs are
global in scope and created at compile time; given something like
for my $x (1..4) {
sub foo { $x }
}
foo();
which instance of $x is foo goint to use? (The answer, in fact, is that
it uses the one from the first time the loop is entered, since that's
the one that existed at compile time.)
> my $prevHELO;
> sub doReceived {
<snip>
> if ($MAIN::prevHELO) {
Um, *what* are you doing here? This is not the 'my $prevHELO' you just
declared, it's a global in the package MAIN (which doesn't usually
exist: the initial default package is called 'main', and package names
are case-sensitive).
(Do I owe Rainer an apology?)
Even if you had used the lexical, you should have expected to keep its
value across calls to the sub, since it is declared outside the scope of
the sub.
In <s58909-86q2....@anubis.morrow.me.uk>, on 02/08/2012
at 03:53 AM, Ben Morrow <b...@morrow.me.uk> said:
>Um, *what* are you doing here?
Well, what I'm *trying* to do is to have a single variable named
$prevHELO that is used inside the while loop and maintained by the
subroutine. I thought that Rainer was suggesting that I prefix the
package name when using the variable inside the subroutine.
>the initial default package is called 'main'
Whoops!
>(Do I owe Rainer an apology?)
No; doReceived is inside the lexical scope, by design. Whether that
design is flawed is a separate issue :-(
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
sub doReceived {
...
if ($prevHELO) {
...
}
...
prevHELO=$HELO;
}
}
1
__END__
>(In detail: because the while loop is at the top level of the
>program, and because perl doesn't quite treat blocks which aren't
>subs as true blocks, it doesn't realise that $prevHELO is declared
>in a section of code which might run more than once.)
Is that reportable as a bug, and is it still the case in Perl 6?
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
In <87wr7y8iph....@sapphire.mobileactivedefense.com>, on 02/07/2012
at 08:57 PM, Rainer Weikusat <rweiku...@mssgmbh.com> said:
>The my-variable is exists in the lexical scope it is defined in and
>since the subroutine is not defined inside the same lexical scope, it
>uses the variable $prevHELO of the current package.
The subroutine is inside the while loop, specifically to give it
access to variables declared in the loop.
>Perl code which achieves what was probably intended:
>----------------
>our $prevHELO;
>while (<>) {
> local $prevHELO;
> print_it();
>}
>sub print_it()
>{
> print("|$prevHELO|");
> $prevHELO = 'bla';
>}
>---------------
Doesn't that cause the subroutine to refer to a *different* variable
with the name $prevHELO?
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
>> >> mailfile: while (my $mailfile=shift) {
>> >> my $prevHELO;
>> >> foreach (@Received[$ReceivedIx..$#Received]) {
>> >> sub doReceived {
>> >> if ($prevHELO) {
>> > It dives a bit into the gory parts of perl, but I think this is you
>> > problem.
>> > 'sub doReceived' generates a function at compile time, refering to the
>> > variable existing at compile time. Therefore it is not using the
>> > variable initialized by the my statement in the outer loop.
>> The my-variable is exists in the lexical scope it is defined in and
>> since the subroutine is not defined inside the same lexical scope, it
>> uses the variable $prevHELO of the current package. Which will of
>> course keep its value unless the value is changed.
> There are no package variables in the code Shmuel posted. The subroutine
> is defined within the lexical scope of $prevHELO, otherwise it would
> have given a strictures error.
It is not defined within this lexical scope in the incomplete code in
the article Peter Makholm replied to and I was referrring to as
well. I usually don't read 'Shmuels' postings because his a
signallless noise. Conceivably, he has also written other code than
this particular example and might have published it elsewhere.
> In <bks809-vcl2....@anubis.morrow.me.uk>, on 02/08/2012
> at 12:35 AM, Ben Morrow <b...@morrow.me.uk> said:
> >Otherwise you'll need to define doReceived outside the loop and pass
> >$prevHELO in as a parameter.
> Will moving the declaration before the while loop and explicitly
> initializing the variable to undef at the beginning of the loop work?
I'm still not entirely clear as to what you are trying to acheive: do
you want the value preserved across iterations of the foreach loop but
reset each time you restart the while loop? In that case yes, what you
suggest will work, but it's not a good way to write it.
In the first place, you still have sub doReceived inside the while loop.
Since it can't really be usefully considered to be within the scope of
the loop, it shouldn't be there.
Secondly, $prevHELO is now effectively a global you are using as a
parameter to doReceived. This is bad style for all the usual reasons, so
you should pass it as a normal parameter instead. Unless I've
misunderstood your logic, this isn't difficult:
> my $prevHELO;
> mailfile: while (my $mailfile=shift) {
> undef $prevHELO;
$prevHELO logically belongs to (one iteration of) the while loop, so
this was the right place to declare it.
Here, however, you need to pass it to doReceived explicitly rather than
assuming it can pick it up implicitly. The logic *is* a little awkward,
given that you want to 'last', but not enormously so. One way of writing
it would be
my $HELO = $+{HELO} // $+{IP};
my $more = doReceived($+{FROM}, $prevHELO, $HELO, ...);
$prevHELO = $HELO;
$more or last;
Another would be to return the new value for $prevHELO, which would be
better if you don't always want to set it to the HELO value passed in.
Yet another would be to pass a *ref* to $prevHELO, which doReceived can
use to set the value for itself; that's a little obscure, since it's
really just a hidden form of return value, but there are occasions where
the flexibility is useful.
> In <s58909-86q2....@anubis.morrow.me.uk>, on 02/08/2012
> at 03:53 AM, Ben Morrow <b...@morrow.me.uk> said:
> >Um, *what* are you doing here?
> Well, what I'm *trying* to do is to have a single variable named
> $prevHELO that is used inside the while loop and maintained by the
> subroutine. I thought that Rainer was suggesting that I prefix the
> package name when using the variable inside the subroutine.
While that would work, at least if you included the 'undef $prevHELO'
you suggested xthread, it has no advantages over the file-scoped lexical
you were using there. As a general rule of thumb the only reason to ever
use package globals is if you (or some module, like Exporter) need to
get at the variable from outside the current file.
Ben Morrow <b...@morrow.me.uk> writes:
> Quoth Shmuel (Seymour J.) Metz <spamt...@library.lspace.org.invalid>:
>> In <s58909-86q2....@anubis.morrow.me.uk>, on 02/08/2012
>> at 03:53 AM, Ben Morrow <b...@morrow.me.uk> said:
>> >Um, *what* are you doing here?
>> Well, what I'm *trying* to do is to have a single variable named
>> $prevHELO that is used inside the while loop and maintained by the
>> subroutine. I thought that Rainer was suggesting that I prefix the
>> package name when using the variable inside the subroutine.
> While that would work, at least if you included the 'undef $prevHELO'
> you suggested xthread,
It will also work when localizing $prevHELO during each loop-iteration.
> it has no advantages over the file-scoped lexical you were using
> there.
It has actually disadvantages: A my-Variable is accessed by indexing
into the appropriate lexical pad, ie, the name is resolved at compile
time, while accesing something which resides in the symbol table of
the package requires a symbol table aka 'hash' lookup.
> As a general rule of thumb the only reason to ever use package
> globals is if you (or some module, like Exporter) need to get at the
> variable from outside the current file.
The other reason would be local: It is possible to create a binding
for a package-global variable which only exists during the dynamic
extent of the lexical scope that established it.
> In <bks809-vcl2....@anubis.morrow.me.uk>, on 02/08/2012
> at 12:35 AM, Ben Morrow <b...@morrow.me.uk> said:
> >(In detail: because the while loop is at the top level of the
> >program, and because perl doesn't quite treat blocks which aren't
> >subs as true blocks, it doesn't realise that $prevHELO is declared
> >in a section of code which might run more than once.)
> Is that reportable as a bug, and is it still the case in Perl 6?
[I realise I didn't answer this bit...]
No, there would be no point reporting it as a bug. Anyone who might be
capable of fixing it is already well aware this is how perl behaves, and
why.
It's a performance tradeoff: in order to avoid the (relatively large)
overhead of setting up a new lexical pad and pulling down the outer
lexicals every time a block is entered, perl cheats and lifts the
lexicals for a block up into the innermost surrounding sub. A certain
amount of bookkeeping is required to make sure they don't end up visible
when they shouldn't have been, but nearly all of that happens at compile
time. Once a block has been compiled it's rather difficult to work out
which section of code a given lexical was originally attached to.
I don't know if it's still the case in Perl 6 (I don't know much about
it) but I suspect not. I believe that at least in principle all blocks
is Perl 6 are true lexical closures; while I'm certain the various
implementations do a certain amount of cheating (since otherwise
performance would be appalling) I suspect the continuation-based control
flow means they are obliged to keep more careful track of lexical scopes
at runtime.
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
In <pcea09-v14....@anubis.morrow.me.uk>, on 02/08/2012
at 02:45 PM, Ben Morrow <b...@morrow.me.uk> said:
>I'm still not entirely clear as to what you are trying to acheive: do
>you want the value preserved across iterations of the foreach loop
>but reset each time you restart the while loop?
Yes.
>In that case yes, what you suggest will work, but it's not a >good way to write it.
The alternatives I'm aware of all seem more awkward.
>so you should pass it as a normal parameter instead.
I'd have to pass it as a reference, which seems more awkward than
having it in a common scope.
> my $HELO = $+{HELO} // $+{IP};
> my $more = doReceived($+{FROM}, $prevHELO, $HELO, ...);
> $prevHELO = $HELO;
> $more or last;
That would defeat my intent of relegating the logic to the subroutine.
>Another would be to return the new value for $prevHELO, which would
>be better if you don't always want to set it to the HELO value
>passed in.
There is more than one variable that must be updated.
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
In <2bra09-5g6....@anubis.morrow.me.uk>, on 02/08/2012
at 06:26 PM, Ben Morrow <b...@morrow.me.uk> said:
>No, there would be no point reporting it as a bug. Anyone who might
>be capable of fixing it is already well aware this is how perl
>behaves, and why.
What about the fact that neither use strcit nor use warnings catches
it?
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamt...@library.lspace.org
> In <2bra09-5g6....@anubis.morrow.me.uk>, on 02/08/2012
> at 06:26 PM, Ben Morrow <b...@morrow.me.uk> said:
> >No, there would be no point reporting it as a bug. Anyone who might
> >be capable of fixing it is already well aware this is how perl
> >behaves, and why.
> What about the fact that neither use strcit nor use warnings catches
> it?
Again, that's well known. For instance, pad.c (which handles lexicals)
has this comment (in S_pad_findlex)
/* set PAD_FAKELEX_MULTI if this lex can have multiple
* instances. For now, we just test !CvUNIQUE(cv), but
* ideally, we should detect my's declared within loops
* etc - this would allow a wider range of 'not stayed
* shared' warnings. We also treated already-compiled
* lexes as not multi as viewed from evals. */
which precisely explains the problem.
Warnings are generally considered best-effort, given that (in principle)
they're only warning you about things you ought to have known already.
If a few cases are missed because it would be rather difficult to catch
them, that's considered an acceptable trade-off.