Perl: How to pass a 2-dimensional array to a subroutine?

I'm trying to pass a 2-dimensional array to a subroutine and return a new array. A new variable is created inside the subroutine, but somehow the initial array is changed after the subroutine is called. At the same time, there are no problems of such type with 1-dimensional arrays.

Here is the code:

#!/usr/bin/perl -w
use strict;

my @motifs=('1230','1011','2121');
my @empty_profile;

for (my $i=0;$i<4;$i++) {
    for (my $j=0;$j<4;$j++) {
        $empty_profile[$i][$j]=1/8;
    }
}

for (my $i=0;$i<4;$i++) {
    for (my $j=0;$j<4;$j++) {
        print("$empty_profile[$i][$j] ");
    }
    print "\n";
}

my @new_profile=profile(\@motifs,\@empty_profile);

print("print it again\n");

for (my $i=0;$i<4;$i++) {
    for (my $j=0;$j<4;$j++) {
        print("$empty_profile[$i][$j] ");
    }
    print "\n";
}

sub profile {
    my @motifs=@{$_[0]};
    my @p=@{$_[1]};

    for (my $i=0; $i<4;$i++) {
        for (my $j=0;$j<3;$j++) {
            my $l=substr($motifs[$j],$i,1);
            $p[$l][$i]+=1/8;
        }
    }
    @p;
}

It prints @empty_profile 2 times - before and after the subroutine call - and its values are changed.

Upvotes: 0

Views: 769

Answers (1)

mpapec
mpapec

Reputation: 50647

You did a shallow copy of @empty_profile, but as every element of it is array reference, make copy of them as well, so original values don't get altered,

my @p = map [ @$_ ], @{$_[1]};

Upvotes: 2

Related Questions