Как избежать модификации ввода в подпрограммах PDL - PullRequest
1 голос
/ 26 июня 2019

Я бы хотел избежать оператора присваивания .= для изменения пользовательского ввода из подпрограммы.

Один из способов избежать этого - выполнить копию ввода внутри подпрограммы. Это лучший способ продолжить? Есть ли другие решения?

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;
}

В моем случае (perl 5.22.1), выполнение последнего скрипта печатает 1 и 0 в две строки. f_0 не изменяет пользовательский ввод на месте, в то время как f_1 делает.

1 Ответ

1 голос
/ 26 июня 2019

Согласно FAQ 6.17 Что происходит, когда у меня есть несколько ссылок на один и тот же объект PDL в разных переменных :

Piddles ведут себя как ссылки Perl во многих отношениях. Поэтому, когда вы говорите

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

, тогда и $b, и $a указывают на одно и то же объект, например затем говоря

$b++; 

будет не создавать копию оригинального piddle, а просто приращение на месте
[...]
Важно помнить «эталонный характер» пиддлов, когда Передача пидла в подпрограммы. Если вы измените входные piddles вы изменить исходный аргумент, а не его копию. Это отличается от некоторые другие языки обработки массивов, но очень эффективные прохождение загадок между подпрограммами. Если вы не хотите изменять исходный аргумент, а точнее его копия, просто создайте копию явно ...

Так что да, чтобы избежать изменения оригинала, создайте копию, как вы это сделали:

my $x = $input->copy;

или альтернативно:

my $x = pdl( $input );
...