Pregunta

He sido mordido un par de veces por olvidar que x = y en Ruby hace que x se refieren al mismo objeto como y;Estoy demasiado acostumbrado a idiomas donde significa, en Ruby términos, x = y.dup.Olvidar esto, me cambie accidentalmente y cuando yo creo que es seguro en el lado derecho de la asignación.

Puedo ver que tendría sentido para evitar simple x = y tareas sin una razón especial, pero lo mismo puede estar al acecho en otros lugares, tales como

name = (person.last_name.blank? ? 'unknown' : person.last_name)

donde más tarde name << title en realidad sería el cambio de persona.apellido y no sólo de nombre.

Si esto ha ocurrido a usted, también, cómo han aprendido a evitar?Hay ciertas banderas rojas o patrones a buscar?¿Mirar con recelo a cada tarea que hacer?¿Utiliza .dup un montón?No sé si la de Ruby uso se conviertan en una segunda naturaleza para mí, así que algunos consejos útiles sería bienvenido.

¿Fue útil?

Solución

Esto puede parecer poco ortodoxo en un (esencialmente imprescindible) de la lengua como Ruby, pero mi consejo es:evitar daños colaterales por no actualizar todos los objetos (excepto cuando sea estrictamente necesario);crear otros nuevos en su lugar.Usted paga un poco de rendimiento pero tendrás un código que es más claro, más compacto, más modular y fácil de depurar.

http://en.wikipedia.org/wiki/Functional_programming

Así, en el ejemplo, acaba de crear una nueva cadena con un nombre nuevo:

complete_name = name + title

Otros consejos

Sólo una adición a tokland la respuesta:

Enfoque funcional insiste en la inmutabilidad de - es decir,no alteración de los objetos existentes, sino en la creación de otro siempre que desee cambiar el original.Esto es algo en contra de la orientación a objetos es un paradigma que Ruby también trae (objetos de mantener su estado interno, que puede ser alterada por llamar a métodos en él), así que usted tiene que equilibrar un poco entre los dos enfoques (por otro lado, se benefician de múltiples paradigmas fácilmente accesibles en un solo idioma).

Por lo tanto, tres cosas para recordar por ahora:

  1. Aprender lo que la asignación en Ruby es:nada pero el nombramiento de un objeto.Así que, cuando usted dice y=x, sólo está diciendo: "le damos otro nombre y a lo que se ha denominado x".
  2. name << title muta objeto de llamado name.
  3. name += title toma objetos con nombre name y title, concatena en otro objeto, y se asigna a ese nuevo nombre de objeto name.No mutar nada.

También me he topado con una situación y que resultó en un error, que me tomó la mitad de un día de averiguar.Esencialmente me hizo algo como esto

hash = {....}
filename = object.file_name
hash.each |k, v| {file_name.gsub!(k, v) if file_name.include? k}

Este código fue dentro de un bucle y en el bucle, se esperaba que la variable file_name se establecen de nuevo valor original.Pero el objeto.file_name fue cambiado, como yo estaba realizando file_name.gsub!.Hay 2 maneras de resolver esto.Reemplazar la .gsub! llamada con file_name = file_name.gsub o hacer file_name = object.file_name.dup.Yo he optado por la segunda opción.

Creo que debemos tener cuidado con los métodos de haber ! y <<, como cambiar el objeto original en el que están actuando, especialmente después de las tareas como esta.

Un método no debe modificar una variable (por ejemplo,utilizando el operador de desplazamiento a) a menos que su definición dice que se va a modificar.

Así:nunca modificar un objeto en un método que no sea: (a) crear o (b) documento que modifica.

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