Strange behavoiur when passing $1 to a sub

H

Heinrich Mislik

Hello,

this program

#!/usr/bin/perl

use warnings;
use strict;

'a' =~ m/(.)/;
warn $1;
unter($1);
warn $1;

sub unter
{
warn $_[0];
'b' =~ m/(.)/;
warn $_[0];
}
__END__

outputs:

a at ./demo.pl line 7.
a at ./demo.pl line 13.
b at ./demo.pl line 15.
a at ./demo.pl line 9.

This means, the value of $_[0] changes during evaluation of the regex
in the subroutine. Even considering $_[0] is an alias to $1, this should
not happen. This looks like entering the sub happens as follows:

1.) Make local copy of $1.
2.) Make $_[0] an alias to $1 (the local copy of $1)

This should be the other way round:

1.) Make $_[0] alias to $1 (the outer $1)
2.) Make local copy of $1.

perl -v

This is perl, v5.10.0 built for cygwin-thread-multi-64int
(with 6 registered patches, see perl -V for more detail)

Cheers

Heinrich
 
S

smallpond

Hello,

this program

#!/usr/bin/perl

use warnings;
use strict;

'a' =~ m/(.)/;
warn $1;
unter($1);
warn $1;

sub unter
{
    warn $_[0];
    'b' =~ m/(.)/;
    warn $_[0];}

__END__

outputs:

a at ./demo.pl line 7.
a at ./demo.pl line 13.
b at ./demo.pl line 15.
a at ./demo.pl line 9.

This means, the value of $_[0] changes during evaluation of the regex
in the subroutine. Even considering $_[0] is an alias to $1, this should
not happen. This looks like entering the sub happens as follows:

1.) Make local copy of $1.
2.) Make $_[0] an alias to $1 (the local copy of $1)

This should be the other way round:

1.) Make $_[0] alias to $1 (the outer $1)
2.) Make local copy of $1.

perl -v

This is perl, v5.10.0 built for cygwin-thread-multi-64int
(with 6 registered patches, see perl -V for more detail)

Cheers

Heinrich

perldoc perlvar
$<digits> "These variables are all read-only and dynamically
scoped to the current BLOCK."

So $_[0] is an alias to the $1 in the current block whose
initial value was your read-only argument. There is no need
for a sub, you can see it just as well here:


'a' =~ m/(.)/;
warn $1;

{
warn $1;
'b' =~ m/(.)/;
warn $1;
}

warn $1;

a at demo.pl line 7.
a at demo.pl line 10.
b at demo.pl line 12.
a at demo.pl line 15.
 
H

Heinrich Mislik

perldoc perlvar
$<digits> "These variables are all read-only and dynamically
scoped to the current BLOCK."

So $_[0] is an alias to the $1 in the current block

That's the point: why is $_[0] an alias to the $1 in th current block?
It really shoud be an alias to the $1 that exists outside of the sub
and so the value of $_[0] shouldn't change when a regex in the sub is used.

Cheers

Heinrich
 
I

Ilya Zakharevich

perldoc perlvar
$<digits> "These variables are all read-only and dynamically
scoped to the current BLOCK."

As usual with Perl docs, this is complete BS.
So $_[0] is an alias to the $1 in the current block

There is no "$1 in the current block". There is exactly one $1. (Its
VALUE is RESTORED when a block ends.)

One should never pass $N variables to subroutines any other way than

f("$3")

Hope this helps,
Ilya
 
H

Heinrich Mislik

There is no "$1 in the current block". There is exactly one $1. (Its
VALUE is RESTORED when a block ends.)

One should never pass $N variables to subroutines any other way than

f("$3")

Hope this helps,

Thanks, yes, things get clear now. Maybe the text for $<digits> in
perldoc perlvar should point to "Temporary Values via local()" in
perldoc perlsub. Thats where "dynamic scoping" is explained in full.

Cheers Heinrich
 
I

Ilya Zakharevich

Thanks, yes, things get clear now. Maybe the text for $<digits> in
perldoc perlvar should point to "Temporary Values via local()" in
perldoc perlsub. Thats where "dynamic scoping" is explained in full.

Will not work too. The semantic of $1 is different from two other
types of localization: via `local *foo' and via `local $foo'. Both
latter variants produce "new VARIABLES". $N have "new VALUES" (IIRC).

IIRC, one of the checks is printing out references to the variables...

Yours,
Ilya
 

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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top