Что означает присвоение 'shift' переменной? - PullRequest
20 голосов
/ 16 августа 2011

Пример:

use strict;
my $file = shift;

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

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

Ответы [ 4 ]

28 голосов
/ 16 августа 2011

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

13 голосов
/ 16 августа 2011

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

Пример:

my @array = (1, 2, 3);
my $value = shift @array;
print $value; # will print '1'
5 голосов
/ 17 августа 2011

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

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

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

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

perl goat.pl "C:\Goat Kids\goat.txt"
2 голосов
/ 18 августа 2011

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

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

1
2
2

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

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";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...