Slayer
Slayer

Reputation: 111

Dereferencing in Perl gives unexpected result

Sub1 can apply a regex1 on an input string (if it's defined) and collect the references to the special hash (%+) and arrays (@- and @+) variables for captured groups in an objs array. Alternatively, the calling function can directly pass the references to special hash and arrays which are directly added to the objs array. Sub1 then iterates over the information in objs array, (does something) and calls Sub2 to further work on a subset of the captured groups.

Sub2 can also apply a regex2 on an input string (if it's defined) and collect the references in another local objs array or directly collect the references to the captured groups in the local objs array depending on how it was called. It then iterates over the objs array and do something with it - however, when I dereference it, it contains information about matched groups of sub1 and not the matched groups collected in Sub2 as expected.

sub sub1{
  my ($content, $grp_hash_ref, $grp_st_ref, $grp_end_ref) = @_;
  my @objs = ();
  if (defined $content){
    while($content =~ m/<some_regex1>/g){
      push(@objs, [\%+, \@-, \@+]);
    }
  } else {
    push(@objs, [$grp_hash_ref, $grp_st_ref, $grp_end_ref]);
  }
  for my $row (@objs){
    my @obj = @$row;
    my (%grp_hash, @grp_st, @grp_end);
    %grp_hash = %{ $obj[0] };
    @grp_st   = @{ $obj[1] };
    @grp_end  = @{ $obj[2] };
    #####################
    # Do something here
    #####################
    # call sub2
    my $new_content = $+{'<some_group_name>'};
    ... = sub2($new_content, undef, undef, undef);
  }
}

sub sub2{
  my ($content, $grp_hash_ref, $grp_st_ref, $grp_end_ref) = @_;
  my @objs = ();
  if (defined $content){
    while($content =~ m/<some_regex2>/g){
      push(@objs, [\%+, \@-, \@+]);
    }
  } else {
    push(@objs, [$grp_hash_ref, $grp_st_ref, $grp_end_ref]);
  }
  for my $row (@objs){
    my @obj = @$row;
    my (%grp_hash, @grp_st, @grp_end);
    %grp_hash = %{ $obj[0] };
    @grp_st   = @{ $obj[1] };
    @grp_end  = @{ $obj[2] };
    print(Dumper(\%grp_hash));  # This incorrectly prints capture groups of regex1 used in sub1
    # I expect capture gorup information of regex2

  }
}

Upvotes: 1

Views: 56

Answers (1)

Schwern
Schwern

Reputation: 164739

while($content =~ m/<some_regex1>/g){
  push(@objs, [\%+, \@-, \@+]);
}

This stores references to the same three variables over and over again. Every time you match a regex those variables will change.

You need to instead store copies.

Upvotes: 2

Related Questions