Что означает присвоение переменной "shift" переменной?

Пример:

use strict;
my $file = shift;

open(IN, $file) || die "Unable to open $file\n";
open(OUT, ">$file.$$") or die $!;

Что происходит с my $file = shift?

Ответы

Ответ 1

Если используется в основной программе, оно будет shift (удалить и вернуть) первое значение из @ARGV, список аргументов вашей программы. Если он используется внутри подпрограммы, он сдвинет первое значение из @_, списка аргументов под. Дополнительную информацию см. В документации .

Ответ 2

Вы можете прочитать документацию на shift. Это очень ясно. shift принимает массив и извлекает первый элемент (фактически удаляя его из массива). Если вы не предоставляете какой-либо массив, он использует @ARGV (аргументы командной строки программы) для чтения данных. Если вы находитесь внутри функции, она использует @_, а именно параметры функции.

Пример:

my @array = (1, 2, 3);
my $value = shift @array;
print $value; # will print '1'

Ответ 3

shift использует переменную @_, которая содержит значения, переданные функции, или shift использует @ARGV для значений, переданных самому script, если shift ссылается вне функции.

ОДНО СЛОВО ПРЕДОСТЕРЕЖЕНИЯ: Вероятно, это разумно, особенно в Windows, где многие пути содержат пробелы, чтобы поместить имя файла и путь в одинарные кавычки, когда вы передаете его функции script или. Это скажет Perl, что вы передаете ему одно скалярное значение, а не массив значений. Вы можете использовать двойные кавычки, если хотите интерполировать часть имени. Например:

my $path = 'C:\Goat Kids';
func("$path\\goat.txt");

Или из командной строки, если вы передаете имя файла непосредственно в script:

perl goat.pl "C:\Goat Kids\goat.txt"

Ответ 4

В предыдущих ответах описывается, как работает shift. Я хотел бы прокомментировать, почему это хорошая идея использовать его в ваших собственных программах.

Perl по умолчанию является языком с пересылкой. Если подпрограмма изменяет свой аргумент, вызывающая сторона увидит эти, иногда неожиданные изменения. Рекомендуется использовать shift для назначения аргумента подпрограммы частной переменной. Таким образом, если вы внесете в него какие-либо изменения, он не будет виден вызывающему. Например, приведенный ниже код выводит

1
2
2

Первая подпрограмма изменяет свой аргумент и вызывающий видит изменение. Вторая подпрограмма изменяет частный copy своего аргумента, и это изменение не отображается в вызывающем.

use strict;
use warnings;

sub pass_by_ref {
    $_[0] = 2;
}

sub pass_by_value {
    my $x = shift @_;
    $x = 3;
}

my $x = 1;
print $x, "\n";
pass_by_ref($x);
print $x, "\n";
pass_by_value($x);
print $x, "\n";