1

I would like to avoid the assignment operator .= to modify the user input from a subroutine.

One way to avoid this is to perform a copy of the input inside the subroutine. Is this the best way to proceed? Are there other solutions?

use PDL;use strict;
my $a=pdl(1);
f_0($a);print "$a\n";
f_1($a);print "$a\n";
sub f_0{
    my($input)=@_;
    my $x=$input->copy;
    $x.=0;
}
sub f_1{
    my($input)=@_;
    $input.=0;
}

In my case (perl 5.22.1), executing last script prints 1 and 0 in two lines. f_0 does not modify user input in-place, while f_1 does.

Stefan Becker
  • 5,695
  • 9
  • 20
  • 30

1 Answers1

2

According to the FAQ 6.17 What happens when I have several references to the same PDL object in different variables :

Piddles behave like Perl references in many respects. So when you say

$a = pdl [0,1,2,3]; $b = $a;   

then both $b and $a point to the same object, e.g. then saying

$b++; 

will not create a copy of the original piddle but just increment in place
[...]
It is important to keep the "reference nature" of piddles in mind when passing piddles into subroutines. If you modify the input piddles you modify the original argument, not a copy of it. This is different from some other array processing languages but makes for very efficient passing of piddles between subroutines. If you do not want to modify the original argument but rather a copy of it just create a copy explicitly...

So yes, to avoid modification of the original, create a copy as you did:

my $x = $input->copy;

or alternatively:

my $x = pdl( $input );
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • Thank you for your answer. I must comment, however, that the sentence "...If you modify the input piddles you modify the original argument, not a copy of it..." is a bit misleading: if in the f_1 subroutine you replace '.=' by '=', then the user input is not modified at all. The assignment operator '.=', which is a PDL thing I think, is important in reproducing this behavior. – Enredanrestos Jun 26 '19 at 23:25