Подтвердить что ты не робот

Использование my с круглыми скобками и только одна переменная

Иногда я вижу код Perl следующим образом:

my ( $variable ) = blah....

В чем смысл размещения круглых скобок вокруг одной переменной? Я думал, что скобки используются только при объявлении нескольких переменных, например:

my ( $var1, $var2, $var3 ) = blah...
4b9b3361

Ответ 1

Существует несколько сценариев, когда есть разница:

  • Когда массив находится на правой стороне

    my @array = ('a', 'b', 'c');
    my  $variable  = @array;           #  3   size of @array
    my ($variable) = @array;           # 'a'  $array[0]
    
  • Когда список находится на правой стороне

    my  $variable  = qw/ a b c d /;    # 'd'  last  item of the list
    my ($variable) = qw/ a b c d /;    # 'a'  first item of the list
    
  • Подпрограмма с переменным (массив/скаляр) возвращаемое значение

    sub myFunction {
      ...
      return (wantarray() ? @array : $scalar);
    }
    my  $variable  = myFunction(...);  # $scalar   from the subroutine
    my ($variable) = myFunction(...);  # $array[0] from the subroutine
    

Ответ 2

Скобки создают контекст списка, который влияет на то, как оценивается правая сторона присваивания.

Сравнение

my $x = grep { /s/ } qw(apples bananas cherries);
print $x;

с

my ($x) = grep { /s/ } qw(apples bananas cherries);
print $x;

Вы часто будете использовать эту конструкцию, когда вы просто хотите захватить первый элемент списка и отбросить остальные.

Ответ 3

Я не Perl pro (во что бы то ни стало, я не), но AFAIK это связано со списками. Perl имеет разные контексты (скалярный, список). Использование ($var) переключается в контекст списка, $var - это скалярный контекст.

my $var = (1, 2, 4); # $var = 4 (last element)
my ($var) = (1, 2, 4); # $var = 1

Пожалуйста, снимите этот ответ, если это абсолютно неправильно:)

Ответ 4

Вы смешиваете две разные вещи. Во-первых, при использовании my для объявления нескольких переменных вам нужно использовать круглые скобки:

my $foo, $bar;  

Не работает, так как считается, что это два разных оператора:

my $foo;
$bar;

Итак, вам нужны скобки для группировки аргумента в список аргументов функции my:

my($foo, $bar);

Во-вторых, у вас есть явная группировка для вызова контекста списка:

$foo, $bar = "a", "b"; # wrong!

Будут рассмотрены три отдельных заявления:

$foo;
$bar = "a";
"b";

Но если вы используете круглые скобки для группировки $foo и $bar в список, оператор присваивания будет использовать контекст списка:

($foo, $bar) = ("a", "b");

Любопытно, что если вы удалите скобки RHS, вы также столкнетесь с hickup:

($foo, $bar) = "a", "b"; # Useless use of a constant (b) in void context

Но это связано с тем, что оператор = имеет более высокий приоритет, чем запятая ,, которую вы можете увидеть в perlop. Если вы попытаетесь:

my @array = ("a", "b");
($foo, $bar) = @array;

Вы получите желаемое поведение без круглых скобок.

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

my @array = ("a", "b");
$foo = @array;
print $foo;

Это печатает 2, потому что массив оценивается в скалярном контексте, а массивы в скалярном контексте возвращают количество элементов, которые они содержат. В этом случае это 2.

Следовательно, такие выражения, как контекст контекста использования:

my ($foo) = @array;          # $foo is set to $array[0], first array element
my ($bar) = ("a", "b", "c"); # $bar is set to "a", first list element

Это способ переопределить скалярный контекст, который подразумевается в скалярном присваивании. Для сравнения, эти назначения находятся в скалярном контексте:

my $foo = @array;            # $foo is set to the number of elements in the array
my $bar = ("a", "b", "c");   # $bar is set to "c", last list element

Ответ 5

Я разместил подробное объяснение по этому вопросу на другом сайте.

[Я не могу опубликовать его здесь. StackOverflow не поддерживает таблицы. Не то, чтобы у кого-то обычно была проблема с внешним подключением к документации.]