Ruby tiene esta forma práctica y conveniente de compartir variables de instancia mediante el uso de claves como
attr_accessor :var
attr_reader :var
attr_writer :var
¿Por qué elegiría attr_reader
o attr_writer
si simplemente podría usar attr_accessor
? ¿Hay algo como el rendimiento (que dudo)? Supongo que hay una razón, de lo contrario no habrían hecho tales llaves.
Respuestas:
Puede usar los diferentes accesores para comunicar su intención a alguien que lea su código y facilitar la escritura de clases que funcionarán correctamente sin importar cómo se llame su API pública.
Aquí, puedo ver que puedo leer y escribir la edad.
Aquí, puedo ver que solo puedo leer la edad. Imagine que lo establece el constructor de esta clase y luego se mantiene constante. Si hubo un mutador (escritor) para la edad y la clase se escribió asumiendo que esa edad, una vez establecida, no cambia, entonces podría producirse un error al llamar al mutador al código.
Pero, ¿qué está pasando detrás de escena?
Si tú escribes:
Eso se traduce en:
Si tú escribes:
Eso se traduce en:
Si tú escribes:
Eso se traduce en:
Sabiendo eso, aquí hay otra forma de pensarlo: si no tuviera los ayudantes attr _... y tuviera que escribir los accesos usted mismo, ¿escribiría más accesos de los que su clase necesitaba? Por ejemplo, si la edad solo necesita ser leída, ¿también escribirías un método que permita que se escriba?
fuente
attr_reader :a
frente adef a; return a; end
confreaks.net/videos/…attr_reader
accesorio definido toma el 86% del tiempo que lo hace el accesorio definido manualmente. Para Ruby 1.9.0, el descriptor deattr_reader
acceso definido toma el 94% del tiempo que el descriptor de acceso definido manualmente. Sin embargo, en todas mis pruebas, los accesores son rápidos: un accesor tarda aproximadamente 820 nanosegundos (Ruby 1.8.7) o 440 nanosegundos (Ruby 1.9). A esas velocidades, necesitará llamar a un accesorio cientos de millones de veces para obtener el beneficio de rendimiento deattr_accessor
mejorar el tiempo de ejecución general en incluso un segundo.attr_accessor :a, :b
Todas las respuestas anteriores son correctas;
attr_reader
yattr_writer
son más convenientes para escribir que escribir manualmente los métodos para los que son shorthands. Aparte de eso, ofrecen un rendimiento mucho mejor que escribir la definición del método usted mismo. Para obtener más información, consulte la diapositiva 152 en adelante de esta charla ( PDF ) de Aaron Patterson.fuente
No todos los atributos de un objeto deben establecerse directamente desde fuera de la clase. Tener escritores para todas sus variables de instancia es generalmente un signo de encapsulación débil y una advertencia de que está introduciendo demasiado acoplamiento entre sus clases.
Como ejemplo práctico: escribí un programa de diseño en el que pones artículos dentro de contenedores. El artículo tenía
attr_reader :container
, pero no tenía sentido ofrecer un escritor, ya que la única vez que el contenedor del artículo debería cambiar es cuando se coloca en uno nuevo, que también requiere información de posicionamiento.fuente
Es importante comprender que los accesores restringen el acceso a variables, pero no a su contenido. En ruby, como en algunos otros lenguajes OO, cada variable es un puntero a una instancia. Entonces, si tiene un atributo para un Hash, por ejemplo, y lo configura como "solo lectura", siempre puede cambiar su contenido, pero no el contenido del puntero. Mira esto:
Como puede ver, es posible eliminar un par clave / valor del Hash @a, como agregar nuevas claves, cambiar valores, etc. Pero no puede apuntar a un nuevo objeto porque es una variable de instancia de solo lectura.
fuente
No siempre desea que sus variables de instancia sean totalmente accesibles desde fuera de la clase. Hay muchos casos en los que tiene sentido permitir el acceso de lectura a una variable de instancia, pero no es posible escribir en ella (por ejemplo, un modelo que recupera datos de una fuente de solo lectura). Hay casos en los que quieres lo contrario, pero no puedo pensar en ninguno que no esté ideado fuera de mi cabeza.
fuente