Что не так в этом выражении Perl? - PullRequest
7 голосов
/ 08 декабря 2011

В чем проблема со следующим. Я получаю $attribute not defined ошибку.

if (my $attribute = $Data->{'is_new'} and $attribute eq 'Y') {
}

Ответы [ 4 ]

10 голосов
/ 08 декабря 2011

use strict; нашел бы проблему.

$ perl -e'use strict; my $attribute = "..." and $attribute eq "Y";'
Global symbol "$attribute" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

Объявление my влияет только на последующие операторы, но не на оператор, в котором находится объявление.(То же самое относится и к объявлениям our и local.) Это означает, что $attribute, который вы создаете с помощью my и которому назначаете, является переменной, отличной от $attribute, который вы сравниваете с Y.Вы хотите

my $attribute = $Data->{'is_new'};
if ($attribute eq 'Y') { ... }

Теперь, если $Data->{is_new} не существует или не определен, $attribute будет неопределенным, и сравнение его с Y выдаст предупреждение.Вы можете избежать этого предупреждения следующим образом:

my $attribute = $Data->{'is_new'};
if (defined($attribute) && $attribute eq 'Y') { ... }

В качестве альтернативы: (5.10 +)

my $attribute = $Data->{'is_new'};
if (($attribute // '') eq 'Y') { ... }
10 голосов
/ 08 декабря 2011

Ты слишком умен. Просто сделай это:

my $attribute = $Data->{'is_new'};

if (defined $attribute && $attribute eq 'Y') { ... }

Проблемы имеют две стороны:

  • У вас есть дополнительный ) в вашем if
  • my в контексте выражения связывается очень плотно; $attribute не находится в лексической области, пока тело условного оператора , в котором оно содержится, не сможет получить к нему доступ из другой ветви and. Вам нужно поднять его до контекста, как в моем примере.
1 голос
/ 08 декабря 2011

Остальные ответы хорошие.Я просто хочу добавить, что если вы хотите избежать загромождения окружающего объема с помощью переменной $attribute, вы можете сделать:

if (($Data->{'is_new'} || '') eq 'Y') {
    # do stuff
}

Это также работает с strict и warnings.

0 голосов
/ 08 декабря 2011

Как уже упоминалось, вы не можете объявить переменную и использовать ее одновременно. Так оно и есть; Вам нужно закончить оператор объявления, прежде чем вы сможете использовать новую переменную.

Что вы могли бы сделать, хотя я, честно говоря, несколько растерялся , почему это еще не было упомянуто, это:

if (my $attribute = $Data->{'is_new'} and $Data->{'is_new'} eq 'Y') 

$attribute еще не объявлено, но $Data->{'is_new'} равно .

Просто чтобы прояснить: смысл этого утверждения, если бы тогда были три вещи:

  • Инициализировать и присвоить значение $attribute
  • Убедитесь, что это значение не определено / пустая строка / ноль
  • Проверьте, является ли это значение 'Y'

Лексическая область действия $attribute является внутренней частью последующего блока if-операторов, не более, не менее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...