В Perl, почему добавление «|| die» в оператор заставляет его вычислять в скалярном контексте? - PullRequest
1 голос
/ 24 июня 2019

В конце концов я обнаружил, что мой код оценивается в скалярном контексте, а не в контексте списка, хотя у меня есть () вокруг назначения.

  • 1-й вопрос: почему добавление «|| die ...» к выражению / присваиванию вызывает его оценку в скалярном контексте?

  • 2-й, есть ли идиома / | die .... ...., которую можно использовать при выполнении назначения списка?

Вот мой пример кода, который демонстрирует проблему.

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper qw(Dumper);

my $h1 = {
    var => "1",
    bar => "1",
    baz => "1",
};

my $h2 = {
    var => "2",
    bar => "2",
    baz => "2",
};

my $ds;
$ds->{rules} = [$h1,$h2];

print "TEST1\n";
print Dumper($ds);

print "TEST2\n";
my (@processes) = @{$ds->{rules}};
print Dumper(\@processes);
print "@processes\n";

print "TEST3\n";
(@processes) = @{$ds->{rules}} || die "unable to get rules form config.. \n";
print Dumper(\@processes);
print "@processes\n";

Вывод:

TEST2
$VAR1 = [
          {
            'bar' => '1',
            'baz' => '1',
            'var' => '1'
          },
          {
            'bar' => '2',
            'baz' => '2',
            'var' => '2'
          }
        ];
HASH(0x25eea68) HASH(0x260b240) 
TEST3
$VAR1 = [
          2
        ];
2

Сравните TEST2 и TEST3.Насколько я могу судить, простое добавление бита || die '.... ' в конец меняет способ вычисления оператора в скалярном контексте, хотя у меня есть круглые скобки в левой части. Q1 : Может быть, я просто плотный, но почему это происходит?

Q2 : существует ли идиома / | die .... ...., которая все еще может использоваться при выполнении назначения списка?

1 Ответ

10 голосов
/ 24 июня 2019

Причина, по которой это вызывает скалярный контекст, заключается в том, что || связывается сильнее, чем =, поэтому

(@processes) = @{$ds->{rules}} || die "unable to get rules form config.. \n";

анализируется как

(@processes) = (@{$ds->{rules}} || die "unable to get rules form config.. \n");

И || создает логический контекст.Однако у perl есть слабосвязывающая версия ||:

(@processes) = @{$ds->{rules}} or die "unable to get rules form config.. \n";

, которая будет проанализирована так, как вы хотите.

...