¿Sabes qué son las variables de instancia en las variables de Ruby?

Las variables de instancia comienzan con un signo at (@) y pueden ser referenciadas sólo dentro de los métodos de clase. Se diferencian de las variables locales en que no existen dentro de un ámbito particular. En su lugar, se almacena una tabla de variables similar para cada instancia de una clase. Las variables de instancia viven dentro de una instancia de clase, así que mientras esa instancia permanezca viva, también lo harán las variables de instancia.

 

Las variables de instancia pueden ser referenciadas en cualquier método de esa clase. Todos los métodos de una clase utilizan la misma tabla de variables de instancia, a diferencia de las variables locales, donde cada método tendrá una tabla de variables diferente. Sin embargo, es posible acceder a las variables de instancia sin definirlas previamente. Esto no levantará una excepción, pero el valor de la variable será nulo y se emitirá una advertencia si ha ejecutado Ruby con el parámetro -w.

 

Este ejemplo demuestra el uso de variables de instancia. Tenga en cuenta que el shebang contiene el interruptor -w, que imprimirá advertencias en caso de que ocurran. Observe también el uso incorrecto fuera de un método en el ámbito de la clase. Esto es incorrecto y se discute a continuación.

#!/usr/bin/env ruby -w

class TestClass

# Incorrect!

@test = "monkey"

def initialize

@value = 1337

end

def print_value

# OK

puts @value

end

def uninitialized

# Technically OK, generates warning

puts @monkey

end

end

t = TestClass.new

t.print_value

t.uninitialized

 

¿Por qué la variable @test es incorrecta? Esto tiene que ver con el alcance y la forma en que Ruby implementa las cosas. Dentro de un método, el alcance de la variable de instancia se refiere a la instancia particular de esa clase. Sin embargo, en el ámbito de la clase (dentro de la clase, pero fuera de cualquier método), el ámbito es el ámbito de la instancia de clase. Ruby implementa la jerarquía de clases mediante la instanciación de objetos Class, por lo que hay una segunda instancia en juego aquí. La primera instancia es una instancia de la clase Class, y aquí es donde @test irá. La segunda instancia es la instanciación de TestClass, y aquí es donde irá @value. Esto se vuelve un poco confuso, pero recuerda nunca usar @instance_variables fuera de los métodos. Si necesita almacenamiento en toda la clase, utilice @class_variables, que pueden utilizarse en cualquier parte del ámbito de la clase (dentro o fuera de los métodos) y se comportarán de la misma manera.

Accesorios

Normalmente no se puede acceder a las variables de instancia desde fuera de un objeto. Por ejemplo, en el ejemplo anterior, no se puede llamar simplemente t.value o t.@value para acceder a la variable de instancia @value. Esto rompería las reglas de la encapsulación. Esto también se aplica a las instancias de clases hijas, no pueden acceder a las variables de instancia pertenecientes a la clase padre aunque técnicamente sean del mismo tipo. Por lo tanto, para proporcionar acceso a las variables de instancia, se deben declarar los métodos accessor.

 

El siguiente ejemplo muestra cómo se pueden escribir los métodos accessor. Sin embargo, tenga en cuenta que Ruby proporciona un acceso directo y que este ejemplo sólo existe para mostrarle cómo funcionan los métodos accesorios. Generalmente no es común ver los métodos de los accesorios escritos de esta manera a menos que se necesite algún tipo de lógica adicional para el accesorio.

#!/usr/bin/env ruby

class Student

def initialize(name,age)

@name, @age = name, age

end

# Name reader, assume name can't change

def name

@name

end

# Age reader and writer

def age

@age

end

def age=(age)

@age = age

end

end

alice = Student.new("Alice", 17)

# It's Alice's birthday

alice.age += 1

puts "Happy birthday #{alice.name}, \

you're now #{alice.age} years old!"

 

Los atajos hacen las cosas un poco más fáciles y compactas. Hay tres de estos métodos de ayuda. Deben ejecutarse en el ámbito de la clase (dentro de la clase pero fuera de cualquier método), y definirán dinámicamente métodos muy parecidos a los definidos en el ejemplo anterior. No hay magia aquí, y parecen palabras clave del lenguaje, pero en realidad son sólo métodos dinámicos de definición. Además, estos accesorios típicamente van en la parte superior de la clase. Esto le da al lector una visión general instantánea de las variables de los miembros que estarán disponibles fuera de la clase o para las clases infantiles.

Hay tres de estos métodos de accesorios. Cada uno de ellos toma una lista de símbolos que describen las variables de instancia a las que se debe acceder.

 

  • attr_reader - Define métodos de "reader", como el método del nombre en el ejemplo anterior.
  • attr_writer - Define métodos "writer" como el método age= en el ejemplo anterior.
  • attr_accessor - Define los métodos "reader" y "writer".

 

#!/usr/bin/env ruby

class Student

attr_reader :name

attr_accessor :age

def initialize(name,age)

@name, @age = name, age

end

end

alice = Student.new("Alice", 17)

# It's Alice's birthday

alice.age += 1

puts "Happy birthday #{alice.name}, \

you're now #{alice.age} years old!"

Cuándo usar las variables de instancia

Ahora que sabes qué son las variables de instancia, ¿cuándo las usas? Las variables de instancia deben usarse cuando representan el estado del objeto. El nombre y la edad del estudiante, sus calificaciones, etc. No deberían usarse para almacenamiento temporal, para eso están las variables locales. Sin embargo, es posible que se puedan utilizar para el almacenamiento temporal entre llamadas de método para cálculos de varias etapas. Sin embargo, si está haciendo esto, es posible que desee reconsiderar la composición del método y convertir estas variables en parámetros del método en su lugar.

(0 votes)