En Ruby, algunos métodos tienen un signo de interrogación ( ?
) que hace una pregunta como include?
esa pregunta si el objeto en cuestión está incluido, esto luego devuelve un verdadero / falso.
Pero, ¿por qué algunos métodos tienen signos de exclamación ( !
) donde otros no?
Qué significa eso?
Respuestas:
En general, los métodos que terminan en
!
indican que el método modificará el objeto al que está llamado . Ruby los llama " métodos peligrosos " porque cambian el estado al que alguien más podría tener una referencia. Aquí hay un ejemplo simple para cadenas:Esto generará:
En las bibliotecas estándar, hay muchos lugares donde verá pares de métodos con nombres similares, uno con
!
y otro sin él. Los que no se llaman "métodos seguros" y devuelven una copia del original con los cambios aplicados a la copia , con la persona que llama sin cambios. Aquí está el mismo ejemplo sin el!
:Esto produce:
Tenga en cuenta que esto es solo una convención, pero muchas clases de Ruby lo siguen. También lo ayuda a realizar un seguimiento de lo que se modifica en su código.
fuente
save
ysave!
enActiveRecord
El signo de exclamación significa muchas cosas, y a veces no se puede distinguir mucho más que "esto es peligroso, tenga cuidado".
Como han dicho otros, en los métodos estándar a menudo se usa para indicar un método que hace que un objeto se mute a sí mismo, pero no siempre. Tenga en cuenta que muchos métodos estándar cambiar su receptor y no tienen un punto (exclamación
pop
,shift
,clear
), y algunos métodos con los signos de exclamación no cambian su receptor (exit!
). Ver este artículo por ejemplo.Otras bibliotecas pueden usarlo de manera diferente. En Rails, un signo de exclamación a menudo significa que el método arrojará una excepción al fallo en lugar de fallar en silencio.
Es una convención de nomenclatura, pero muchas personas la usan de maneras sutilmente diferentes. En su propio código, una buena regla general es usarlo siempre que un método esté haciendo algo "peligroso", especialmente cuando existen dos métodos con el mismo nombre y uno de ellos es más "peligroso" que el otro. Sin embargo, "peligroso" puede significar casi cualquier cosa.
fuente
Esta convención de nomenclatura se levanta de Scheme .
fuente
! normalmente significa que el método actúa sobre el objeto en lugar de devolver un resultado. Del libro Programming Ruby :
fuente
¡Es más exacto decir que los métodos con un Bang! son la versión más peligrosa o sorprendente . Hay muchos métodos que mutan sin una explosión, como
.destroy
y en general, los métodos solo tienen explosiones donde existe una alternativa más segura en la biblioteca principal.Por ejemplo, en Array tenemos
.compact
y.compact!
, ambos métodos mutan la matriz, pero.compact!
devuelve nil en lugar de self si no hay nil en la matriz, lo cual es más sorprendente que solo self.El único método no mutante que he encontrado con una explosión es
Kernel
el.exit!
que es más sorprendente que.exit
porque no se puede atraparSystemExit
mientras el proceso se está cerrando.Rails y ActiveRecord continúan esta tendencia, ya que utiliza la explosión para obtener más efectos 'sorprendentes' como los
.create!
que generan errores en caso de falla.fuente
De themomorohoax.com:
Se puede usar una explosión de las siguientes maneras, en orden de preferencia personal.
El punto es: solo usa una explosión cuando realmente hayas pensado si es necesario, para salvar a otros desarrolladores de la molestia de tener que verificar por qué estás usando una explosión.
La explosión proporciona dos pistas a otros desarrolladores.
http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods
fuente
Explicación simple:
Pero si alguna vez llamó a un método
downcase!
en la explicación anterior,foo
cambiaría a downcase permanentemente.downcase!
no devolvería un nuevo objeto de cadena, sino que reemplazaría la cadena en su lugar, cambiando totalmentefoo
a minúscula. Te sugiero que no uses adowncase!
menos que sea totalmente necesario.fuente
Me gusta pensar en esto como un cambio explosivo que destruye todo lo que sucedió antes. Explosión o signo de exclamación significa que está realizando un cambio guardado permanente en su código.
Si usa, por ejemplo, el método de Ruby para la sustitución global
gsub!
la sustitución que realice es permanente.Otra forma de imaginarlo es abrir un archivo de texto y buscar y reemplazar, seguido de guardar.
!
hace lo mismo en tu código.Otro recordatorio útil si vienes del mundo bash es que
sed -i
tiene este efecto similar de hacer un cambio guardado permanente.fuente
Los llamados "métodos destructivos" tienden a cambiar la copia original del objeto al que se refiere.
fuente
En
!
pocas palabras: los métodos simplemente cambian el valor del objeto al que se les llama, mientras que un método sin!
devuelve un valor manipulado sin escribir sobre el objeto sobre el que se invocó el método.Úselo solo
!
si no planea necesitar el valor original almacenado en la variable a la que llamó el método.Prefiero hacer algo como:
O
En vez de
Por si acaso quisiera acceder al valor original nuevamente.
fuente
!
muta el objeto en lugar de devolver una copia modificada.User.create!