Respuestas:
Son casi sinónimos, pero no del todo. La diferencia es que !tiene una precedencia mayor que not, mucho como &&y ||son de mayor precedencia que andy or.
!tiene la precedencia más alta de todos los operadores, y notuna de las más bajas, puede encontrar la tabla completa en los documentos de Ruby .
Como ejemplo, considere:
!true && false
=> false
not true && false
=> true
En el primer ejemplo, !tiene la mayor prioridad, por lo que efectivamente está diciendo false && false.
En el segundo ejemplo, nottiene una precedencia menor que true && false, por lo que "cambió" el falsede true && falsea true.
La pauta general parece ser que debe seguir !, a menos que tenga una razón específica para usarla not. !en Ruby se comporta igual que la mayoría de los otros lenguajes, y es "menos sorprendente" que not.
unlessen ese caso?
unlesssimplemente no es realmente favorecido en el mundo del rubí. El consenso general es que se interpone cuando !funciona igual de bien en la mayoría de las situaciones. Estoy seguro de que hay casos en los que a menos que sea más expresivo, pero me mantengo alejado.
unlessesté desfavorecido. Lo más cercano que tenemos a un consenso dice lo contrario.
notpuede ser. En Python, a veces asigno valores booleanos a variables para facilitar la lectura de las declaraciones if. Eso podría significar usar el patrón x = not y, donde y es algo complejo. En Ruby, x = !yfunciona, pero x = not yconsigue syntax error, unexpected tIDENTIFIER, expecting '('. El orden de prioridad significa esto necesita paréntesis alrededor de la derecha de la op asignación a un trabajo: x = (not y).