Pregunta

En Ruby, algunos métodos tienen un signo de interrogación (? ) que hace una pregunta como include? que pregunta si el objeto en cuestión está incluido, esto luego devuelve un verdadero / false.

Pero, ¿por qué algunos métodos tienen signos de exclamación (! ) donde otros no los tienen?

¿Qué significa?

¿Fue útil?

Solución

En general, los métodos que terminan en ! indican que el método modificará el objeto al que se llama . Ruby llama a estos como " métodos peligrosos " porque cambian de estado al que otra persona podría tener una referencia. Aquí hay un ejemplo simple para cadenas:

foo = "A STRING"  # a string called foo
foo.downcase!     # modifies foo itself
puts foo          # prints modified foo

Esto dará como resultado:

a string

En las bibliotecas estándar, hay muchos lugares donde verás pares de métodos con nombres similares, uno con ! y otro sin. Los que están sin se denominan "métodos seguros" y devuelven una copia del original con los cambios aplicados a la copia , sin cambiar la persona que llama. Este es el mismo ejemplo sin el ! :

foo = "A STRING"    # a string called foo
bar = foo.downcase  # doesn't modify foo; returns a modified string
puts foo            # prints unchanged foo
puts bar            # prints newly created bar

Esto produce:

A STRING
a string

Ten en cuenta que esto es solo una convención, pero muchas clases de Ruby lo siguen. También le ayuda a realizar un seguimiento de lo que se está modificando en su código.

Otros consejos

El signo de exclamación significa muchas cosas y, a veces, no se puede decir mucho de ello, excepto que "esto es peligroso, ten 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 cambian su receptor y no tienen un signo de exclamación ( pop , shift , clear ) y algunos métodos con exclamación Los puntos no cambian su receptor ( exit! ). Consulte 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 lanzará una excepción en caso de falla 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 de oro 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. " Peligroso " aunque puede significar casi cualquier cosa.

Esta convención de nomenclatura se elimina de Scheme .

  

1.3.5 convenciones de nombres

     

Por convención, los nombres de los procedimientos.   que siempre devuelve un valor booleano   usualmente terminan en ``? ''. Tales procedimientos   se llaman predicados.

     

Por convención, los nombres de los procedimientos.   que almacenan valores en previamente   ubicaciones asignadas (ver sección 3.4)   usualmente termina en ``! ''. Tales procedimientos   Se llaman procedimientos de mutación. Por   convención, el valor devuelto por un   el procedimiento de mutación no está especificado.

! normalmente significa que el método actúa sobre el objeto en lugar de devolver un resultado. Del libro Ruby de programación :

  

Métodos que son " peligrosos, " o modifique el receptor, podría nombrarse con un final "! " ;.

Desde themomorohoax.com:

Una explosión puede usarse de las siguientes formas, en orden de preferencia personal.

  

1) Un método de registro activo genera un error si el método no funciona   lo que diga será.

     

2) Un método de registro activo guarda el registro o un método guarda un   objeto (por ejemplo, tira!)

     

3) Un método hace algo & # 8220; extra & # 8221 ;, como publicaciones en algún lugar, o hace   Algo de acción.

El punto es: solo usa una explosión cuando & # 8217; realmente hayas pensado si Es necesario, para ahorrar a otros desarrolladores la molestia de tener que comprueba por qué estás utilizando un bang.

El bang proporciona dos señales a otros desarrolladores.

  

1) que no es necesario guardar el objeto después de llamar al   método.

     

2) cuando llames al método, la db se va a cambiar.

http: // www .themomorohoax.com / 2009/02/11 / when-to-use-a-bang-exclamation-point-after-rails-method

Es más exacto decir que los métodos con un Bang! son los más peligroso o sorprendente versión. Hay muchos métodos que mutan sin un Bang, como < code> .destroy y en general los métodos solo tienen bangs donde existe una alternativa más segura en la biblioteca central.

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's en la matriz, lo que es más sorprendente que simplemente devolver self.

El único método no mutante que he encontrado con un bang es el Kernel de .exit! que es más sorprendente que .exit porque no puede detectar < código> SystemExit mientras el proceso se está cerrando.

Rails y ActiveRecord continúan con esta tendencia porque usan bang para obtener efectos más 'sorprendentes' como .create! que genera errores en caso de fallo.

Explicación simple:

foo = "BEST DAY EVER" #assign a string to variable foo.

=> foo.downcase #call method downcase, this is without any exclamation.

"best day ever"  #returns the result in downcase, but no change in value of foo.

=> foo #call the variable foo now.

"BEST DAY EVER" #variable is unchanged.

=> foo.downcase! #call destructive version.

=> foo #call the variable foo now.

"best day ever" #variable has been mutated in place.

Pero si alguna vez ha llamado a un downcase! método en la explicación anterior, foo cambiaría a downcase permanentemente. downcase! no devolvería un nuevo objeto de cadena, pero reemplazaría la cadena en su lugar, cambiando totalmente el foo a downcase. Le sugiero que no utilice downcase! a menos que sea totalmente necesario.

!

Me gusta pensar en esto como un cambio explosivo que destruye todo lo que ha pasado antes. Un signo de exclamación significa que está haciendo un cambio guardado permanente en su código.

Si utiliza, por ejemplo, el método de Ruby para la sustitución global gsub! , la sustitución que realice es permanente.

Otra forma en que puedes imaginarlo es abrir un archivo de texto y buscar y reemplazar, seguido de guardar. ! hace lo mismo en su código.

Otro recordatorio útil si vienes del mundo bash es que sed -i tiene este efecto similar de hacer un cambio guardado permanente.

Llamados " Métodos destructivos " Tienden a cambiar la copia original del objeto al que se refiere.

numbers=[1,0,10,5,8]
numbers.collect{|n| puts n*2} # would multiply each number by two
numbers #returns the same original copy
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array
numbers   # returns [nil,nil,nil,nil,nil]

Línea inferior: los métodos ! simplemente cambian el valor del objeto al que se les solicita, mientras que un método sin ! devuelve un valor manipulado sin escribir sobre el objeto el método fue llamado

Solo use ! si no planea necesitar el valor original almacenado en la variable a la que llamó el método.

Prefiero hacer algo como:

foo = "word"
bar = foo.capitalize
puts bar

O

foo = "word"
puts foo.capitalize

En lugar de

foo = "word"
foo.capitalize!
puts foo

En caso de que quiera acceder nuevamente al valor original.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top