Acceder a la variable de instancia desde fuera de la clase


82

Si una variable de instancia pertenece a una clase, ¿puedo acceder a la variable de instancia (por ejemplo @hello) directamente usando la instancia de la clase?

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
puts h.method1

Respuestas:


148

Sí, puedes usarlo instance_variable_getasí:

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1                        #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"

Si la variable no está definida (primera llamada de instance_variable_geten mi ejemplo) se obtiene nil.


Como Andrew menciona en su comentario:

No debe hacer que esta sea la forma predeterminada de acceder a las variables de instancia, ya que viola la encapsulación.

Una mejor forma es definir un descriptor de acceso:

class Hello
  def method1
    @hello = "pavan"
  end
  attr_reader :hello  
end

h = Hello.new
p h.hello #nil
p h.method1                        #"pavan" - initialization of @hello
p h.hello #"pavan"

Si desea que otro nombre del método, se puede crear un alias el descriptor de acceso: alias :my_hello :hello.

Y si la clase no está definida en su código, sino en una gema: puede modificar clases en su código e insertar nuevas funciones en las clases .


6
Usted debe no hacer de esta manera el valor por defecto se accede a las variables de instancia, ya que viola la encapsulación.
Andrew Marshall

@knut, ¿no podemos hacer esto como h = Hello.newy h.method1y h.hello?
nik7

3
@nlingutla Puede definir un descriptor de acceso conattr_reader :hello
knut

¿No sería alias my_hello helloasí alias :my_hello :hello?
Financia la demanda de Monica

1
Para mí, esto es genial para las especificaciones, donde no quieres hacer algo público.
baash05

20

También puede lograr esto llamando attr_readero attr_accessorasí:

class Hello
  attr_reader :hello

  def initialize
    @hello = "pavan"
  end
end

o

class Hello
  attr_accessor :hello

  def initialize
    @hello = "pavan"
  end
end

Llamar attr_readercreará un getterpara la variable dada:

h = Hello.new
p h.hello        #"pavan"

La llamada attr_accessorcreará un getterAND a setterpara la variable dada:

h = Hello.new
p h.hello        #"pavan"
h.hello = "John"
p h.hello        #"John"

Como puede comprender, use attr_readery en attr_accessorconsecuencia. Úselo solo attr_accessorcuando necesite un getterAND settery úselo attr_readercuando solo necesite ungetter

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.