Как отличается поведение if- и if! утверждение влияет на диапазон-оператор в скалярном контексте?

На http://novosial.org/perl/one-liner/ я обнаружил следующее два однострочных. Выходы отличаются, потому что оператор unless отличается от if ! (из-за правил ассоциативности и приоритета).

cat file:  
foo  



bar  
perl -ne 'print unless /^$/../^$/' file  
foo  
bar  
perl -ne 'print if ! /^$/../^$/' file  
foo  

bar  

Как различное поведение оператора if ! заставляет второй однострочный вывод выводить одну пустую строку?


person sid_com    schedule 07.03.2010    source источник


Ответы (3)


Как говорится в связанной статье, это вопрос ассоциативности и приоритета ...

print unless /^$/../^$/ эквивалентно print if !(/^$/../^$/)

print if ! /^$/../^$/ эквивалентно print if (!/^$/)../^$/

Обратите внимание, что первое отрицает выражение диапазона, а второе отрицает условие начала диапазона, но не сам диапазон.

person Dave Sherohman    schedule 07.03.2010

Ответ, ИМХО, заключается в том, что в Perl нет оператора if !: есть оператор if и есть оператор !. Оператор ! не привязан к if; он оперирует своим аргументом. Если вы начнете думать такими категориями, ваша жизнь станет проще.

Итак, в вашем случае у вас есть

do_something() unless something;

и

do_something() if something-else;

Давайте заключим в обычно невидимые скобки:

do_something() unless ( something );

и

do_something() if ( something-else );

В этом случае вы пытались написать something-else так, чтобы истинное значение этого условия было эквивалентно истинному something, но не приняли во внимание тот факт, что оператор ! тесно связывает.

Вот почему есть not.

Пытаться

perl -ne 'print if not /^$/../^$/' file  

См. not в perldoc perlop:

Унарный not возвращает логическое отрицание выражения справа от него. Это эквивалент !, за исключением очень низкого приоритета.

person Sinan Ünür    schedule 07.03.2010

Проверка диапазона вернет истину до тех пор, пока второй операнд не станет истинным. Затем он вернет false при следующем вызове.

Этот фрагмент сообщает нам, что возвращает оператор диапазона.

perl -ne "$x= ( ! /^$/../^$/ ) ; print qq/$x : $_/" range_test.TXT

который производит

1 : foo
2E0 :
 :
 :
1 : bar

Таким образом, первая пустая строка генерирует истинный ответ, следующая - ложный.

person justintime    schedule 07.03.2010