Si te encuentras con algo que no comprendes nos puedes dejar un comentario y te responderemos tan rápido como podamos.
Solución:
Digamos que tienes una clase Person
.
class Person
end
person = Person.new
person.name # => no method error
Obviamente nunca definimos el método name
. Vamos a hacer eso.
class Person
def name
@name # simply returning an instance variable @name
end
end
person = Person.new
person.name # => nil
person.name = "Dennis" # => no method error
Ajá, podemos leer el nombre, pero eso no significa que podamos asignar el nombre. Esos son dos métodos diferentes. El primero se llama lector y el ultimo se llama escritor. Todavía no creamos al escritor, así que hagámoslo.
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"
Increíble. Ahora podemos escribir y leer la variable de instancia @name
utilizando métodos de lectura y escritura. Excepto que esto se hace con tanta frecuencia, ¿por qué perder el tiempo escribiendo estos métodos cada vez? Podemos hacerlo más fácil.
class Person
attr_reader :name
attr_writer :name
end
Incluso esto puede volverse repetitivo. Cuando desee tanto el lector como el escritor, ¡simplemente use el accesor!
class Person
attr_accessor :name
end
person = Person.new
person.name = "Dennis"
person.name # => "Dennis"
¡Funciona de la misma manera! Y adivina qué: la variable de instancia @name
en nuestro objeto persona se configurará como cuando lo hicimos manualmente, por lo que puede usarlo en otros métodos.
class Person
attr_accessor :name
def greeting
"Hello #@name"
end
end
person = Person.new
person.name = "Dennis"
person.greeting # => "Hello Dennis"
Eso es todo. Para entender cómo attr_reader
, attr_writer
y attr_accessor
los métodos realmente generan métodos para usted, lea otras respuestas, libros, documentos de Ruby.
attr_accessor es solo un método. (El enlace debería proporcionar más información sobre cómo funciona: mire los pares de métodos generados y un tutorial debería mostrarle cómo usarlo).
el truco es que class
es no es una definición en Ruby (es “solo una definición” en lenguajes como C++ y Java), pero es una expresión que evalúa. Es durante esta evaluación cuando el attr_accessor
se invoca el método que a su vez modifica la clase actual; recuerde el receptor implícito: self.attr_accessor
donde self
es el objeto de clase “abierto” en este punto.
La necesidad de attr_accessor
y amigos, es, bueno:
-
Ruby, como Smalltalk, no permite acceder a las variables de instancia fuera de los métodos1 para ese objeto. Es decir, no se puede acceder a las variables de instancia en el
x.y
formulario como es común en, por ejemplo, Java o incluso Python. en rubíy
siempre se toma como un mensaje para enviar (o “método para llamar”). Por lo tanto, laattr_*
los métodos crean contenedores que representan la instancia@variable
acceso a través de métodos creados dinámicamente. -
repetitivo apesta
Espero que esto aclare algunos de los pequeños detalles. Codificación feliz.
1 Esto no es estrictamente true y hay algunas “técnicas” en torno a esto, pero no hay soporte de sintaxis para el acceso de “variable de instancia pública”.
attr_accessor
es (como dijo @pst) solo un método. Lo que hace es crear más métodos para usted.
Así que este código aquí:
class Foo
attr_accessor :bar
end
es equivalente a este código:
class Foo
def bar
@bar
end
def bar=( new_value )
@bar = new_value
end
end
Puedes escribir este tipo de método tú mismo en Ruby:
class Module
def var( method_name )
inst_variable_name = "@#method_name".to_sym
define_method method_name do
instance_variable_get inst_variable_name
end
define_method "#method_name=" do |new_value|
instance_variable_set inst_variable_name, new_value
end
end
end
class Foo
var :bar
end
f = Foo.new
p f.bar #=> nil
f.bar = 42
p f.bar #=> 42
Comentarios y calificaciones
Eres capaz de añadir valor a nuestro contenido añadiendo tu veteranía en las reseñas.