Сравните две (потенциально) переменные undef в perl

Я пытаюсь сравнить две переменные, в которых обычно находятся строки. Эти переменные генерируются из базы данных, $var1 из одного db и $var2 из другого. Когда я сравниваю их в цикле, я использую оператор ne. Однако есть моменты, когда я эти переменные null или undef. Сравнение выполняется следующим образом:

foreach my $var1 (@$varlist)
{
  if ($var1 ne $var2)
  {
    print "vars are not equal";
  }
}

Проблема в том, что если $var1 или $var2 являются undef, я получаю сообщение об ошибке. Тем не менее, мне нужно иметь возможность сравнивать тогда значения как undef b/c, мне придется их написать. Я рассматривал преобразование переменных в строку "NULL", а затем назад, но это казалось неэффективным.

Любой способ исправить это? Спасибо!

Ответ 1

Проверьте, также ли они определены:

foreach my $var1 (@$varlist)
    if ( ! defined $var1 || ! defined $var2 || $var1 ne $var2 )
        print "vars are not equal";

Это означает, что они не равны, если оба являются undefined. Если вы хотите другое поведение, просто измените выражение if.

Ответ 2

Это не ошибка сравнения значений undefined, это просто предупреждение. Мне нравится использовать оператор Perl // (требуется >= v5.10) в таких случаях, чтобы гарантировать, что операторы определены:

if (($var1 // '') ne ($var2 // '')) { ... }

будет обрабатывать строку undefined как пустую строку во время сравнения, например.

Поскольку вы хотите, чтобы операнды имели определенное значение при печати (NULL была одной возможностью), вы также можете рассмотреть использование оператора //=.

if (($var1 //= 'NULL') ne ($var2 //= 'NULL')) {
   print "$var1 and $var2 are not equal";
}

установит значение $var1 или $var2 на 'NULL', если они undefined, а затем выполните сравнение.

Ответ 3

Кажется, что вы практикуете безопасный Perl, используя use warnings;, но теперь вы, возможно, пришли к тому, что вы выборочно отключили их. Эти предупреждения предназначены для вашей собственной защиты, однако, если вы знаете, что собираетесь сравнивать возможные строки undef, просто отключайте их немного (команда no является локальной для закрывающего блока, поэтому они снова включаются).

use strict;
use warnings;

foreach my $var1 (@$varlist)
{
  no warnings 'uninitialized';
  if ($var1 ne $var2)
  {
    print "vars are not equal";
  }
}