Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion about using perl @_ variable with regex capture

Tags:

perl

When I using following code, subroutine f can't print @_ correctly for the substitution of $tmp before it, which is explainable.

use strict;
use warnings;

sub f {
  # print("args = ", @_);
  my $tmp = "111";
  $tmp =~ s/\d+//;
  print("args = ", @_);
}

"dd11ddd" =~ /(?<var>\d+)/;
f($+{"var"});

But when I uncomment the first print statement, then both print could give the correct @_, which makes me confused, why the capture group hasn't been overwrite. Or just some underlay mechanism of perl I don't know? Please help, thanks.

When I pass capture group into perl subroutine, the capture group hasn't been overwritten as expected. I want to know why this could happen and how to explain it correctly.

like image 781
rodman10 Avatar asked Jan 27 '26 04:01

rodman10


1 Answers

Perl arguments are passed by reference.

sub f {
   $_[0] = "def";
}

my $x = "abc;
say $x;   # abc
f( $x );
say $x;   # def

%+ is affected by $tmp =~ s/\d+//, and thus so is $_[0]. We don't usually run into problems because we usually make an explicit copy of the arguments.

sub f {
   my $y = shift;
   $y = "def";
}

my $x = "abc";
say $x;   # abc
f( $x );
say $x;   # abc

Passing a copy of the scalar would also avoid the problems.

sub f {
   $_[0] = "def";
}

my $x = "abc";
say $x;   # abc
f( "$x" );
say $x;   # abc

The above explains why you get weird behaviour and how to avoid it, but not why accessing $_[0] before the substitution seems to fix it. Honestly, it doesn't really matter. It's some weird interaction between the magical nature of %+, the implicit localization of %+, the optimizations to avoid needless implication localizations of %+, and the way localization works.

like image 83
ikegami Avatar answered Jan 28 '26 20:01

ikegami



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!