Diferença entre `not` e`! `Em ruby

Respostas:

143

Eles são quase sinônimos, mas não exatamente. A diferença é que !tem uma precedência mais alta que not, muito parecido com &&e ||são de uma precedência mais alta que ande or.

!tem a precedência mais alta de todos os operadores, e notuma das mais baixas, você pode encontrar a tabela completa nos documentos Ruby .

Como exemplo, considere:

!true && false
=> false

not true && false
=> true

No primeiro exemplo, !tem a precedência mais alta , então você está efetivamente dizendo false && false.
No segundo exemplo, nottem uma precedência menor do que true && false, então isso "mudou" falsede true && falsepara true.

A orientação geral parece ser que você deve seguir !, a menos que tenha um motivo específico para usar not. !em Ruby se comporta da mesma forma que a maioria das outras linguagens, e é "menos surpreendente" do que not.

Brennan
fonte
6
Eu usei 'não' no passado para tornar as condicionais negadas mais fáceis de ler. Ou seja, se a totalidade da condicional for negada, eu me sinto confortável usando 'não' em vez de '!' Gosto quando meu código parece inglush
jaydel
@jaydel Você poderia usar unlessnesse caso?
Jacob
1
@Jacob, sim, definitivamente. unlesssimplesmente não é muito popular no mundo do rubi. O consenso geral é que isso só atrapalha quando !funciona tão bem na maioria das situações. Tenho certeza de que há casos em que a menos pode ser mais expressiva, mas evito.
Brennan
4
Eu discordo que unlessé desfavorecido. A coisa mais próxima que temos de um consenso diz o contrário.
Adam Lassek
1
Só queria compartilhar um exemplo de como notpode ser surpreendente . Em Python, às vezes atribuo booleanos a variáveis ​​para tornar as instruções if mais fáceis de ler. Isso pode significar usar o padrão x = not y, onde y é algo complexo. Em Ruby, x = !yfunciona, mas x = not yconsegue syntax error, unexpected tIDENTIFIER, expecting '('. A ordem de precedência significa que este precisa de parênteses em torno do direito da op atribuição ao trabalho: x = (not y).
S. Kirby
13

Uma maneira fácil de entender o notoperador é olhando not true && falsecomo equivalente a!(true && false)

Roniegh
fonte