my VAR = EXPR if COND

G

grin.k1tt3n

I just discovered the bug/feature of having a static variable if it
initialized as:

my $var = expr() if condition();

That is, if condifition is not true, then var is initialized with
whatever was last there.

It seems like this issue is over 7 years old, but I see no mention of
it in "man perlsub".
(It cost me two hours this morning wrangling with mod_perl).

Are there any plans to document/correct this soon?

This was running on perl 5.8.8.

Thanks,
Rob
 
R

Rafal Konopka

I just discovered the bug/feature of having a static variable if it
initialized as:

my $var = expr() if condition();

That is, if condifition is not true, then var is initialized with
whatever was last there.
I think it's always safer to declare the variable first (particularly
inside loops) and then set it to some value:

my $var;
$var = expr() if condition();

Rafal
 
K

Klaus

I just discovered the bug/feature of having a static variable if it
initialized as:

my $var = expr() if condition();

That is, if condifition is not true, then var is initialized with
whatever was last there.

It seems like this issue is over 7 years old, but I see no mention of
it in "man perlsub".

I found something in "perlsyn", sub-paragraph "statement modifiers":
=================================================

"The behaviour of a my statement modified with a statement modifier
conditional or loop construct (e.g. my $x if ...) is undefined. The
value of the my variable may be 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."
 
D

DJ Stunks

I just discovered the bug/feature of having a static variable if it
initialized as:

my $var = expr() if condition();

That is, if condifition is not true, then var is initialized with
whatever was last there.

It seems like this issue is over 7 years old, but I see no mention of
it in "man perlsub".
(It cost me two hours this morning wrangling with mod_perl).

Are there any plans to document/correct this soon?

This was running on perl 5.8.8.

I don't think I understand what you're getting at. Either that or I
don't see it:

C:\>perl -Mstrict -e "for (1,0) {my $var = 'defined' if $_; \
print qq[$_: \$var = $var\n]}"
1: $var = defined
0: $var =

??

This is perl, v5.8.7 built for MSWin32-x86-multi-thread

-jp
 
B

Ben Morrow

Quoth "DJ Stunks said:
I just discovered the bug/feature of having a static variable if it
initialized as:

my $var = expr() if condition();

That is, if condifition is not true, then var is initialized with
whatever was last there.

It seems like this issue is over 7 years old, but I see no mention of
it in "man perlsub".
(It cost me two hours this morning wrangling with mod_perl).

Are there any plans to document/correct this soon?

This was running on perl 5.8.8.

I don't think I understand what you're getting at. Either that or I
don't see it:

C:\>perl -Mstrict -e "for (1,0) {my $var = 'defined' if $_; \
print qq[$_: \$var = $var\n]}"
1: $var = defined
0: $var =

??

This is perl, v5.8.7 built for MSWin32-x86-multi-thread

I believe the OP is referring to this behaviour:

~% perl -le'sub foo { my $x if 0; print $x++ } foo; foo;'
0
1
~%

which is a way of faking 'static' variables (note that without the C<if
0> you get 0 both times). This has always been undocumented (technically
it's a bug), and in bleadperl (the dev track for 5.10) it has been
replaced with proper static vars declared with the C<state> keyword. I'm
not sure what will happen to this construct then: I wouldn't be
surprised if it was fixed... so don't rely on it.

Ben
 
H

Heinrich Mislik

I just discovered the bug/feature of having a static variable if it
initialized as:

my $var = expr() if condition();

That is, if condifition is not true, then var is initialized with
whatever was last there.

It seems like this issue is over 7 years old, but I see no mention of
it in "man perlsub".
(It cost me two hours this morning wrangling with mod_perl).

Are there any plans to document/correct this soon?

It is in perdoc perlsyn:

NOTE: The behaviour of a "my" statement modified with a statement modi-
fier conditional or loop construct (e.g. "my $x if ...") is undefined.
The value of the "my" variable may be "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.

cheers

heinrich
 
D

DJ Stunks

Ben said:
I believe the OP is referring to this behaviour:

~% perl -le'sub foo { my $x if 0; print $x++ } foo; foo;'
0
1
~%

which is a way of faking 'static' variables (note that without the C<if
0> you get 0 both times). This has always been undocumented (technically
it's a bug), and in bleadperl (the dev track for 5.10) it has been
replaced with proper static vars declared with the C<state> keyword. I'm
not sure what will happen to this construct then: I wouldn't be
surprised if it was fixed... so don't rely on it.

so "static variable" would be synonymous with "private variable" as
through a closure?

C:\>perl -Mstrict -le "{my $x; sub foo {print $x++}} foo; foo;"
0
1

?

-jp
 
D

David Squire

DJ said:
so "static variable" would be synonymous with "private variable" as
through a closure?

ITIM "static" as in one of the many uses of that keyword in C/C++: a
variable that is static to a function retains its value between function
calls. They are declared, for example, as "static int ever_called = 0;".

This functionality is similar to a variable declared outside a
subroutine in a closure, though I suspect that there is more to closures
than that (at least in other languages) - and in Perl you can have
multiple subs in the same closure.


DS
 
B

Ben Morrow

Quoth David Squire said:
ITIM "static" as in one of the many uses of that keyword in C/C++: a
variable that is static to a function retains its value between function
calls. They are declared, for example, as "static int ever_called = 0;".
Yes.

This functionality is similar to a variable declared outside a
subroutine in a closure,

This is not about closures. Named subs don't close over their variables
in Perl, yet

{
my $x = 0;
sub foo { print $x++ }
}

will behave as above, indeed is the 'correct' way to declare it. The
disadvantage is that you have to create the extra scope outside the sub:
with C<state> vars you don't.

A closure is different in that you can end up with several different
copies of the sub with *different* copies of the variable: with

sub mkcounter {
my $x;
return sub { $x++ };
}

each time you call mkcounter you get a new counter, whereas with named
subs (which aren't closures)

sub mkcounter {
my $x;
sub counter { $x++ }
return \&counter;
}

there is only one, and you get a 'Variable "%s" will not stay shared'
warning to let you know that. Of course, sub names are global in scope,
so there's little point declaring one inside another anyway.
though I suspect that there is more to closures
than that (at least in other languages) - and in Perl you can have
multiple subs in the same closure.

I'm not sure what you mean by that: a closure is just a sub+lexical
scope (padlist), so each closure 'contains' exactly one sub...

Ben
 
J

Joe Smith

I just discovered the bug/feature of having a static variable if it
initialized as:

my $var = expr() if condition();

That's why I use

my $var = condition() ? expr() : undef;

so that the value of $var is always determinate.
-Joe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,125
Messages
2,570,748
Members
47,301
Latest member
SusannaCgx

Latest Threads

Top