Como o comportamento diferente do a menos que- e "se!" A declaração influencia o operador de alcance no contexto escalar?
-
25-09-2019 - |
Pergunta
Sobre http://novosial.org/perl/one-liner/ Encontrei as duas frases seguintes. As saídas são diferentes porque o unless
declaração é diferente de if !
(devido às regras de associatividade e precedência).
cat file: foo bar
perl -ne 'print unless /^$/../^$/' file foo bar
perl -ne 'print if ! /^$/../^$/' file foo bar
Como o comportamento diferente do if !
-Statement Faça da segunda linha de uma linha uma linha em branco?
Solução
Como diz o artigo vinculado, é uma questão de associativa e precedência ...
print unless /^$/../^$/
é equivalente a print if !(/^$/../^$/)
print if ! /^$/../^$/
é equivalente a print if (!/^$/)../^$/
Observe que o primeiro nega a expressão do intervalo, enquanto o segundo nega a condição inicial da faixa, mas não o próprio alcance.
Outras dicas
A resposta, IMHO, é que não há if !
declaração em perl: existe um if
declaração e existe um !
operador. o !
O operador não se liga a if
; Ele opera em seu argumento. Se você começar a pensar nesses termos, sua vida será mais fácil.
Então, no seu caso, você tem,
do_something() unless something;
e
do_something() if something-else;
Vamos colocar os parênteses normalmente invisíveis:
do_something() unless ( something );
e
do_something() if ( something-else );
Nesse caso, você tentou escrever something-else
para que o valor da verdade dessa condição seja equivalente à verdade de something
, mas não conseguiu levar em consideração o fato de que !
O operador se liga firmemente.
É por isso que existe not
.
Tentar
perl -ne 'print if not /^$/../^$/' file
Unário
not
Retorna a negação lógica da expressão à sua direita. É o equivalente a!
exceto pela precedência muito baixa.
O teste de intervalo retornará verdadeiro ao tempo em que o segundo operando é verdadeiro. Ele retornará false na próxima chamada.
Este trecho nos diz o que o operador de alcance está retornando
perl -ne "$x= ( ! /^$/../^$/ ) ; print qq/$x : $_/" range_test.TXT
que produz
1 : foo
2E0 :
:
:
1 : bar
Portanto, a primeira linha em branco gera uma resposta verdadeira, a próxima falsa