Что не так с этим if-утверждением? - PullRequest
2 голосов
/ 11 апреля 2011

У меня есть этот код

#!/usr/bin/perl

use warnings;
use strict;

my $nis = "qqq";
my $grp = "pre-qqq";

if ($nis eq $grp || 'pre-' . $nis eq $grp) {
    print "match1\n";
}

if (($nis || 'pre-' . $nis) eq $grp) {
    print "match2\n";
}

, где первое if -общение работает, а второе - нет.

Что не так со вторым?

Можно ли это сделать без повторения переменных дважды?

Ответы [ 5 ]

5 голосов
/ 11 апреля 2011

Поскольку первое делает (потенциально) два сравнения, первое сравнивает $nis с $grp и, если это не удается, сравнивает 'pre-'.$nis с $grp, тогда как второе будет только когда-либо делать одно сравнение, $nis || 'pre-'.$nis против $grp.

Ваша проблема в том, что $nis || 'pre-'.$nis не является квантовой суперпозицией , которая может принимать любое значение в зависимости от того, как вы на это смотрите, это одно значение либо $nis , либо 'pre-'.$nis.Если $nis является правдивым (то есть это не пустая строка, undef, число 0 или строка «0»), тогда это значение будет $nis.Если нет, то это значение будет 'pre-'.$nis (что, учитывая правила истинности, означает, что 'pre-'.$nis будет когда-либо только 'pre-' или 'pre-0').

Если вы хотите сравнить с двумязначения, как правило, вам нужно сделать два сравнения ... но вы можете сделать это конкретное сравнение за один шаг, сделав значение, которое вы проверяете по регулярному выражению:

if ($grp =~ /^(:?pre-)?$nis/) {
    print "match3\n";
}

I 'Впрочем, я буду придерживаться вашего первого сравнения для удобства чтения.

4 голосов
/ 11 апреля 2011

Что неправильно, так это то, что «(A или B) равно C», а «(A равно C) или (B равно C)» означают совершенно разные вещи.Во втором if вы просили Perl сначала вычислить $nis || 'pre-'.$nis, а затем посмотреть, равно ли оно $grp.

Вычисление $nis || 'pre-'.$nis (своего рода) обрабатывает $nis и 'pre-'.$nisкак логические (истина / ложь) значения.Точнее, результат равен $nis, если это не значение, которое Perl считает «ложным»;в противном случае он равен 'pre-'.$nis.В этом случае "qqq" не является ложным, поэтому значение просто "qqq".Поскольку это не равно $grp, условие в вашем втором if является ложным.

На обычном языке, если вы говорите: «3 или 6 простое» или «Джо или Боб Элленбрат ", человеческий слушатель будет интерпретировать это так, как я думаю, вы хотите, чтобы ваш второй if был интерпретирован.Но это не то, как работает любой компьютерный язык, который я знаю.(Полу исключение: «Икона» Грисуорла.)

2 голосов
/ 11 апреля 2011
if ( $grp ~~ [ $nis, "pre-$nis" ] ) {
    print "match\n";
}

или (до 5.10.1)

if ( grep $_ eq $grp, $nis, "pre-$nis" ) {
    print "match\n";
}
1 голос
/ 24 июля 2012

strpos возвращает позицию индекса того места, где он впервые обнаружил $ needle, который может быть равен 0. Так как 0 также принимает значение false, решение заключается в использовании строгого сравнения: if (false! == strpos ($ haystack, $ needle) ...

1 голос
/ 11 апреля 2011

($ nis || 'pre-'. $ Nis) оценивается как 'pre-'. $ nis, только если $ nis не определен, 0 или пустая строка. так что в вашем случае это всегда оценивается как ($ nis eq $ grp) {... придерживайтесь вашего первого подхода, и вы будете в порядке

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