Saltar al contenido

Uso de variables de instancia en métodos de clase – Ruby

Solución:

La razón por la que las variables de instancia funcionan en clases en Ruby es que las clases de Ruby están instancias en sí mismas (instancias de la clase Class). Pruébelo usted mismo inspeccionando DummyClass.class. No hay “métodos estáticos” en el sentido de C # en Ruby porque cada método se define en (o se hereda) en alguna instancia y se invoca en alguna instancia. En consecuencia, pueden acceder a cualquier variable de instancia que esté disponible en el destinatario.

Ya que DummyClass es una instancia, puede tener sus propias variables de instancia muy bien. Incluso puede acceder a esas variables de instancia siempre que tenga una referencia a la clase (que debería ser siempre porque los nombres de clase son constantes). En cualquier momento, podrá llamar ::DummyClass.instance_variable_get(:@arr) y obtenga el valor actual de esa variable de instancia.

En cuanto a si es bueno hacerlo, depende de los métodos.

Si @arr es lógicamente el “estado” de la instancia / clase DummyClass, luego guárdelo en la variable de instancia. Si @arr solo se usa en dummy_method2 como un atajo operativo, luego páselo como un argumento. Para dar un ejemplo donde se usa el enfoque de variable de instancia, considere ActiveRecord en Rails. Te permite hacer esto:

u = User.new
u.name = "foobar"
u.save

Aquí, el nombre que se le ha asignado al usuario son datos que están legítimamente sobre el usuario. Si, antes del #save llamar, si se preguntara “cuál es el nombre del usuario en este punto”, respondería “foobar”. Si profundiza lo suficiente en los aspectos internos (profundizará mucho y en una gran cantidad de metaprogramación, encontrará que usan variables de instancia exactamente para esto).

El ejemplo que he usado contiene dos invocaciones públicas independientes. Para ver un caso en el que las variables de instancia todavía se usan a pesar de que solo se realiza una llamada, observe la implementación de ActiveRecord de #update_attributes. El cuerpo del método es simplemente load(attributes, false) && save. Por que #save no se pasan argumentos (como el nuevo name) a pesar de que va a estar en el cuerpo de save donde algo como UPDATE users SET name="foobar" WHERE id=1;? Es porque cosas como el nombre son información que pertenece a la instancia.

A la inversa, podemos ver un caso en el que no tendría sentido usar variables de instancia. Mira la implementación de #link_to_if, un método que acepta un argumento tipo booleano (generalmente una expresión en el código fuente) junto con argumentos que normalmente son aceptados por #link_to como la URL a la que enlazar. Cuando la condición booleana es verdadera, debe pasar el resto de los argumentos a #link_to e invocarlo. No tendría mucho sentido asignar variables de instancia aquí porque no diría que el contexto de invocación aquí (el renderizador) contiene esa información en la instancia. El renderizador en sí no tiene una “URL para enlazar” y, por lo tanto, no debe estar enterrado en una variable de instancia.

Esas son variables de instancia de clase y son cosas perfectamente legítimas en ruby: las clases también son objetos (instancias de Class) y, por lo tanto, tienen variables de instancia.

Una cosa a tener en cuenta es que cada subclase tendrá su propio conjunto de variables de instancia de clase (después de todo, estos son objetos diferentes): DummyClass, los métodos de clase de la subclase no podrían ver @arr.

Variables de clase (@@foo) son, por supuesto, al revés: toda la jerarquía de clases comparte las mismas variables de clase.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *