2012-06-26 2 views
10

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

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

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

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

ответ

11

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

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

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

+0

Почему бы не напечатать выражение, если только '$ var1' не определен? – Prateek

+0

Это было больше основанием для моего ответа, поэтому я выбрал его. Окончательный ответ выглядел так: 'if ((определено! $ Var1 &&! Defined $ var2) && (определено $ var1 && определено $ var2 && $ var1 eq $ var2))' – Prateek

+3

Более короткая версия с использованием xor: 'if ((определено $ var1 xor определено $ var2) или $ var1 ne $ var2) ' –

7

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

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

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

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

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

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

+0

Мне нравится эта концепция и буду использовать ее где-то в другом месте, но это было не то, что я искал. – Prateek

5

Кажется, что вы практикуете безопасный 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"; 
    } 
} 
+2

Одно из предостережений с этим советом состоит в том, что строковое сравнение undef и пустой строки вернет true - что может быть или не быть тем, что требуется. –

Смежные вопросы