Respostas:
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.
unlessnesse caso?
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.
unlessé desfavorecido. A coisa mais próxima que temos de um consenso diz o contrário.
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).