Como o comportamento diferente do a menos que- e "se!" A declaração influencia o operador de alcance no contexto escalar?

StackOverflow https://stackoverflow.com/questions/2395808

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?

Foi útil?

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  

Ver not em PerlDoc Perlop:

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top