¿Attr_accessor funciona de la misma manera en Git? Estoy descubriendo que algunos tutoriales no explican lo suficiente y otros suponen conocimiento previo.
Angelfirenze
10
@Angelfirenze, gitno tiene nada que ver attr_accessor. Git es un software de control de versiones, mientras que attr_accessores un método en Ruby .
Uzbekjon
Respuestas:
2360
Digamos que tienes una clase Person.
classPersonend
person =Person.new
person.name # => no method error
Obviamente nunca definimos el método name. Vamos a hacer eso.
classPersondef name
@name# simply returning an instance variable @nameendend
person =Person.new
person.name # => nil
person.name ="Dennis"# => no method error
Ajá, podemos leer el nombre, pero eso no significa que podamos asignarle el nombre. Esos son dos métodos diferentes. El primero se llama lector y el segundo se llama escritor . Todavía no creamos el escritor, así que hagámoslo.
classPersondef name
@nameenddef name=(str)@name= str
endend
person =Person.new
person.name ='Dennis'
person.name # => "Dennis"
Increíble. Ahora podemos escribir y leer variables de instancia @nameusando métodos de lector y escritor. 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.
classPerson
attr_reader :name
attr_writer :name
end
Incluso esto puede volverse repetitivo. Cuando quieras que tanto el lector como el escritor solo usen el descriptor
classPerson
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 @nameen nuestro objeto persona se establecerá como cuando lo hicimos manualmente, por lo que puedes usarla en otros métodos.
Eso es. Para entender cómo attr_reader, attr_writery los attr_accessormétodos realmente generan métodos para usted, lea otras respuestas, libros, documentos de ruby.
@hakunin: gracias por esa respuesta clara. Lo que me falta es por qué la sintaxis de Ruby sugiere dos puntos ':' para las variables de instancia en la declaración attr_ *? Parece que sería más sencillo usar la misma sintaxis '@' que se usa en otra parte de la clase para referirse a la variable.
Será
207
@WilliamSmith Para responder a su pregunta, debe comprender que attr_accessores un método llamado en la clase actual, y :namees un parámetro que pasa a ese método. No es una sintaxis especial, es una simple llamada al método. Si @nametuviera que darle variable, no tendría sentido, porque @name lo contendría nil. Entonces sería como escribir attr_accessor nil. No le está pasando una variable que necesita crear, le está pasando el nombre al que desea que se llame la variable.
Max Chernyak
23
@hakunin: eso tiene mucho sentido. Acabo de enterarme hoy de que Ruby en realidad está 'ejecutándose' a medida que analiza un archivo y que cada declaración y expresión es en realidad una llamada a un método en algún objeto. Incluyendo attr_accessor. Muy útil.
Será
52
usé Rails por 3 años, nunca lo supe. Vergüenza
Sean Xiao
55
@Buminda sí, pero método namey variable @nameno son lo mismo. No los confundas. Tiene una variable de instancia @nameen su clase, y define attr_reader :namepoder leerla desde el exterior. Sin attr_readerno hay una manera simple de acceder @namefuera de su clase.
Max Chernyak
127
attr_accessor es solo un método . (El enlace debería proporcionar más información sobre cómo funciona: observe los pares de métodos generados y un tutorial le mostrará cómo usarlo).
El truco es que noclass 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 attr_accessorse invoca el método que a su vez modifica la clase actual: recuerde el receptor implícito: self.attr_accessordónde selfestá el objeto de clase "abierto" en este punto.
La necesidad de attr_accessor y amigos, es, bueno:
Ruby, como Smalltalk, no permite acceder a variables de instancia fuera de los métodos 1 para ese objeto. Es decir, no se puede acceder a las variables de instancia en la x.yforma como es común en, por ejemplo, Java o incluso Python. En Ruby ysiempre se toma como un mensaje para enviar (o "método para llamar"). Por lo tanto, laattr_* métodos crean contenedores que representan el @variableacceso a la instancia a través de métodos creados dinámicamente.
La repetitiva apesta
Espero que esto aclare algunos de los pequeños detalles. Feliz codificación
1 Esto no es estrictamente cierto y existen algunas "técnicas" en torno a esto , pero no hay soporte de sintaxis para el acceso de "variable de instancia pública".
Cuando dices que attr_accessor es "solo un método", lo entiendo. Pero, ¿cómo se llama la sintaxis para llamar a ese método? Tengo problemas para encontrar la sección en la documentación de ruby que habla de sintaxis como some_method: name => "whatever",: notherName,: etc
BT
68
attr_accessores (como dijo @pst) solo un método. Lo que hace es crear más métodos para ti.
Entonces este código aquí:
classFoo
attr_accessor :bar
end
es equivalente a este código:
classFoodef bar
@barenddef bar=( new_value )@bar= new_value
endend
Puede escribir este tipo de método usted mismo en Ruby:
classModuledef 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
endendendclassFoo
var :bar
end
f =Foo.new
p f.bar #=> nil
f.bar =42
p f.bar #=> 42
Este es un gran ejemplo de dónde se usa la metaprogramación incluso en los escenarios de nivel más principiante. Muy agradable.
John Simon
2
Estaba buscando un boceto de implementación attr_accessory ¡por fin lo encontré aquí! Aunque resolvió mi problema, pero tengo curiosidad por saber dónde (libro / documento oficial) ¿puedo encontrar un ejemplo de implementación como este?
Wasif Hossain
40
attr_accessor es muy simple:
attr_accessor :foo
es un atajo para:
def foo=(val)@foo= val
enddef foo
@fooend
no es más que un captador / definidor de un objeto
Tu respuesta está bien. 'Atajo' significa "una ruta alternativa más corta" según mi diccionario, no "sintaxis de azúcar" o "macro interpretada por el intérprete".
bowsersenior
25
Básicamente, falsifican atributos de datos de acceso público, que Ruby no tiene.
Aunque este comentario no es del todo útil, es cierto. Destaca el hecho de que los atributos de datos públicos no existen fuera de los métodos "get" en Ruby, que es información realmente útil para alguien que intenta aprender el idioma.
Eric Dand
3
Esto realmente no debería ser rechazado. Como un tipo que no es Ruby tratando de resolver esto, ¡esta respuesta es muy útil!
Brad
1
De acuerdo, parece muy similar al nombre de C # {get; set;}
David Miler
17
Es solo un método que define los métodos getter y setter para variables de instancia. Un ejemplo de implementación sería:
defself.attr_accessor(*names)
names.each do|name|
define_method(name){instance_variable_get("@#{name}")}# This is the getter
define_method("#{name}="){|arg| instance_variable_set("@#{name}", arg)}# This is the setterendend
¡manejar múltiples atributos de esta manera es genial!
Wasif Hossain
Este fue un fragmento de código realmente útil para resolver otra pregunta que tenía relacionada con la metaprogramación.
alexventuraio
15
Explicación simple sin ningún código
La mayoría de las respuestas anteriores usan código. Esta explicación intenta responderla sin usar ninguna, a través de una analogía / historia:
Las partes externas no pueden acceder a los secretos internos de la CIA
Imaginemos un lugar realmente secreto: la CIA. Nadie sabe lo que está sucediendo en la CIA, aparte de las personas dentro de la CIA. En otras palabras, las personas externas no pueden acceder a ninguna información en la CIA. Pero debido a que no es bueno tener una organización que es completamente secreta, cierta información se pone a disposición del mundo exterior, solo cosas que la CIA quiere que todos sepan, por supuesto: por ejemplo, el Director de la CIA, qué tan ecológico se compara este departamento a todos los demás departamentos gubernamentales, etc. Otra información: por ejemplo, quiénes son sus agentes encubiertos en Irak o Afganistán; este tipo de cosas probablemente permanecerán en secreto durante los próximos 150 años.
Si está fuera de la CIA, solo puede acceder a la información que ha puesto a disposición del público. O para usar el lenguaje de la CIA, solo puede acceder a la información que está "borrada".
La información que la CIA quiere poner a disposición del público en general fuera de la CIA se llama: atributos.
El significado de los atributos de lectura y escritura:
En el caso de la CIA, la mayoría de los atributos son "solo lectura". Esto significa que si usted es una parte externa a la CIA, puede preguntar: "¿quién es el director de la CIA?" y obtendrás una respuesta directa. Pero lo que no puede hacer con los atributos de "solo lectura" es hacer cambios en la CIA. por ejemplo, no puede hacer una llamada telefónica y de repente decidir que desea que Kim Kardashian sea el Director, o que desea que Paris Hilton sea el Comandante en Jefe.
Si los atributos le dieron acceso de "escritura", entonces podría hacer cambios si lo desea, incluso si estuviera fuera. De lo contrario, lo único que puede hacer es leer.
En otras palabras, los accesores le permiten realizar consultas o hacer cambios a organizaciones que de otro modo no dejarían entrar a personas externas, dependiendo de si los accesos son de lectura o escritura.
Los objetos dentro de una clase pueden acceder fácilmente entre sí
Por otro lado, si ya estaba dentro de la CIA, podría llamar fácilmente a su agente de la CIA en Kabul porque esta información es fácilmente accesible dado que ya está dentro. Pero si está fuera de la CIA, simplemente no se le dará acceso: no podrá saber quiénes son (acceso de lectura), y no podrá cambiar su misión (acceso de escritura).
Exactamente lo mismo con las clases y su capacidad para acceder a variables, propiedades y métodos dentro de ellas. HTH! Cualquier pregunta, por favor pregunte y espero poder aclarar.
¡Tu explicación tiene sentido! +1 Lo sentimos, ¿estás seguro de que la expresión "información que ha sido borrada por la CIA es correcta?"
kouty
Hay varios niveles de "autorización" en la CIA: por ejemplo, Top Secret (nadie más que el Prez), o confianza pública (todos pueden leer esa información). ¡La CIA en realidad proporciona muchos hechos geniales!
BKSpurgeon
Te mereces el voto a favor solo por los ejemplos de Kardashian, Paris Hilton :) Pensé que ya era bastante malo con Trump para el presidente, ¡imagina a los dos a cargo!
rmcsharry
¡Si! ¡Eso es lo que necesitamos, StackOverflow sin código! :-)
Marvin
13
Si está familiarizado con el concepto OOP, debe estar familiarizado con el método getter y setter. attr_accessor hace lo mismo en Ruby.
Getter y Setter en General Way
classPersondef name
@nameenddef name=(str)@name= str
endend
person =Person.new
person.name ='Eshaan'
person.name # => "Eshaan"
Método Setter
def name=(val)@name= val
end
Método Getter
def name
@nameend
Método Getter y Setter en Ruby
classPerson
attr_accessor :name
end
person =Person.new
person.name ="Eshaan"
person.name # => "Eshaan"
explicación perfecta! Es un comportamiento muy útil y puede anularse con demasiada facilidad.
Rubyrider
12
También enfrenté este problema y escribí una respuesta algo larga a esta pregunta. Ya hay algunas respuestas geniales sobre esto, pero cualquiera que busque más aclaraciones, espero que mi respuesta pueda ayudar
Método de inicialización
Initialize le permite establecer datos en una instancia de un objeto al crear la instancia en lugar de tener que establecerlos en una línea separada en su código cada vez que crea una nueva instancia de la clase.
classPersondef initialize(name)@name= name
enddef greeting
"Hello #{@name}"endend
person =Person.new("Denis")
puts person.greeting
En el código anterior, estamos configurando el nombre "Denis" utilizando el método initialize pasando a Dennis a través del parámetro en Initialize. Si quisiéramos establecer el nombre sin el método de inicialización, podríamos hacerlo así:
En el código anterior, establecemos el nombre llamando al método setter attr_accessor usando person.name, en lugar de establecer los valores al inicializar el objeto.
Ambos "métodos" de hacer este trabajo, pero inicializar nos ahorran tiempo y líneas de código.
Este es el único trabajo de inicialización. No puede llamar a initialize como método. Para obtener realmente los valores de un objeto de instancia, debe usar getters y setters (attr_reader (get), attr_writer (set) y attr_accessor (ambos)). Consulte a continuación para obtener más detalles al respecto.
Getters, attr_reader: El propósito completo de un getter es devolver el valor de una variable de instancia particular. Visite el código de muestra a continuación para obtener un desglose de esto.
En el código anterior, llama a los métodos "nombre_elemento" y "cantidad" en la instancia del elemento "ejemplo". El "pone example.item_name" y "example.quantity" devolverá (u "obtendrá") el valor de los parámetros que se pasaron al "ejemplo" y los mostrará en la pantalla.
Afortunadamente, en Ruby hay un método inherente que nos permite escribir este código de manera más sucinta; El método attr_reader. Vea el código a continuación;
Esta sintaxis funciona exactamente de la misma manera, solo que nos ahorra seis líneas de código. ¿Imagínese si tuviera 5 estados más atribuibles a la clase Item? El código se alargaría rápidamente.
Setters, attr_writer: Lo que me sorprendió al principio con los métodos setter es que, a mis ojos, parecía realizar una función idéntica al método de inicialización. A continuación explico la diferencia basada en mi comprensión;
Como se indicó anteriormente, el método de inicialización le permite establecer los valores para una instancia de un objeto tras la creación del objeto.
Pero, ¿qué sucede si desea establecer los valores más tarde, después de crear la instancia, o cambiarlos después de que se hayan inicializado? Este sería un escenario en el que usaría un método de establecimiento. Esa es la diferencia. No tiene que "establecer" un estado particular cuando está utilizando el método attr_writer inicialmente.
El siguiente código es un ejemplo del uso de un método setter para declarar el valor item_name para esta instancia de la clase Item. Tenga en cuenta que seguimos utilizando el método getter attr_reader para que podamos obtener los valores e imprimirlos en la pantalla, en caso de que desee probar el código por su cuenta.
El siguiente código es una reiteración del ejemplo de inicialización anterior de dónde estamos utilizando initialize para establecer el valor de objetos de item_name en la creación.
Creo que parte de lo que confunde a los nuevos Rubyists / programadores (como yo) es:
"¿Por qué no puedo decirle a la instancia que tiene un atributo dado (por ejemplo, nombre) y darle un valor a ese atributo de una vez?"
Un poco más generalizado, pero así es como me hizo clic:
Dado:
classPersonend
No hemos definido Persona como algo que puede tener un nombre. o cualquier otro atributo para el caso.
Entonces si entonces:
baby =Person.new
... e intenta darles un nombre ...
baby.name ="Ruth"
Obtenemos un error porque, en Rubyland, una clase de objeto Persona no es algo asociado o capaz de tener un "nombre" ... ¡todavía!
PERO podemos usar cualquiera de los métodos dados (ver respuestas anteriores) como una forma de decir: "Una instancia de una clase Persona ( baby) ahora puede tener un atributo llamado 'nombre', por lo tanto, no solo tenemos una forma sintáctica de obtener y establecer ese nombre, pero tiene sentido que lo hagamos ".
Nuevamente, abordando esta pregunta desde un ángulo ligeramente diferente y más general, pero espero que esto ayude a la próxima instancia de la Persona de clase que encuentra su camino hacia este hilo.
ownery balanceno son, técnicamente, un método , sino un atributo. La clase BankAccount no tiene def ownery def balance. Si es así, puede usar los dos comandos a continuación. Pero esos dos métodos no están ahí. Sin embargo, puede acceder a los atributos como si tuviera acceso a un método a través de attr_accessor!! De ahí la palabraattr_accessor . Atributo. Accesor Accede a atributos como accedería a un método.
Agregar le attr_accessor :balance, :ownerpermite leer y escribir balancey owner"método". Ahora puede usar los últimos 2 métodos.
Define un atributo con nombre para este módulo, donde el nombre es symbol.id2name, creando una variable de instancia (@name) y un método de acceso correspondiente para leerlo. También crea un método llamado nombre = para establecer el atributo.
Para resumir un atributo, el descriptor de acceso attr_accessor le ofrece dos métodos gratuitos.
Como en Java, se llaman getters y setters.
Muchas respuestas han mostrado buenos ejemplos, así que voy a ser breve.
#the_attribute
y
# the_attribute =
En los viejos documentos de ruby, una etiqueta hash # significa un método. También podría incluir un prefijo de nombre de clase ... MyClass # my_method
Soy nuevo en Ruby y tuve que lidiar con la comprensión de la siguiente rareza. Podría ayudar a alguien más en el futuro. Al final es como se mencionó anteriormente, donde 2 funciones (def myvar, def myvar =) ambas se obtienen implícitamente para acceder a @myvar, pero estos métodos pueden anularse mediante declaraciones locales.
classFoo
attr_accessor 'myvar'def initialize
@myvar="A"
myvar ="B"
puts @myvar# A
puts myvar # B - myvar declared above overrides myvar methodenddef test
puts @myvar# A
puts myvar # A - coming from myvar accessor
myvar ="C"# local myvar overrides accessor
puts @myvar# A
puts myvar # C
send "myvar=","E"# not running "myvar =", but instead calls setter for @myvar
puts @myvar# E
puts myvar # Cendend
Los atributos son componentes de clase a los que se puede acceder desde fuera del objeto. Se conocen como propiedades en muchos otros lenguajes de programación. Se puede acceder a sus valores utilizando la "notación de puntos", como en object_name.attribute_name. A diferencia de Python y algunos otros lenguajes, Ruby no permite acceder a variables de instancia directamente desde fuera del objeto.
classCardef initialize
@wheels=4# This is an instance variableendend
c =Car.new
c.wheels # Output: NoMethodError: undefined method `wheels' for #<Car:0x00000000d43500>
En el ejemplo anterior, c es una instancia (objeto) de la clase Car. Intentamos sin éxito leer el valor de la variable de instancia de ruedas desde fuera del objeto. Lo que sucedió es que Ruby intentó llamar a un método llamado ruedas dentro del objeto c, pero no se definió dicho método. En resumen, object_name.attribute_name intenta llamar a un método llamado attribute_name dentro del objeto. Para acceder al valor de la variable ruedas desde el exterior, necesitamos implementar un método de instancia con ese nombre, que devolverá el valor de esa variable cuando se llame. Eso se llama un método de acceso. En el contexto general de programación, la forma habitual de acceder a una variable de instancia desde fuera del objeto es implementar métodos de acceso, también conocidos como métodos getter y setter.
En el siguiente ejemplo, hemos agregado métodos getter y setter a la clase Car para acceder a las variables de las ruedas desde fuera del objeto. Esta no es la "forma Ruby" de definir captadores y establecedores; solo sirve para ilustrar lo que hacen los métodos getter y setter.
classCardef wheels # getter method@wheelsenddef wheels=(val)# setter method@wheels= val
endend
f =Car.new
f.wheels =4# The setter method was invoked
f.wheels # The getter method was invoked# Output: => 4
El ejemplo anterior funciona y un código similar se usa comúnmente para crear métodos getter y setter en otros idiomas. Sin embargo, Ruby proporciona una forma más simple de hacer esto: tres métodos integrados llamados attr_reader, attr_writer y attr_acessor. El método attr_reader hace que una variable de instancia sea legible desde el exterior, attr_writer la hace escribible y attr_acessor la hace legible y escribible.
El ejemplo anterior se puede reescribir así.
classCar
attr_accessor :wheels
end
f =Car.new
f.wheels =4
f.wheels # Output: => 4
En el ejemplo anterior, el atributo de ruedas será legible y escribible desde fuera del objeto. Si en lugar de attr_accessor, usáramos attr_reader, sería de solo lectura. Si usáramos attr_writer, sería de solo escritura. Esos tres métodos no son getters y setters en sí mismos, pero, cuando se los llama, crean métodos getter y setter para nosotros. Son métodos que generan dinámicamente (mediante programación) otros métodos; Eso se llama metaprogramación.
El primer ejemplo (más largo), que no emplea los métodos integrados de Ruby, solo debe usarse cuando se requiere código adicional en los métodos getter y setter. Por ejemplo, un método de establecimiento puede necesitar validar datos o hacer algún cálculo antes de asignar un valor a una variable de instancia.
Es posible acceder (leer y escribir) variables de instancia desde fuera del objeto, utilizando los métodos incorporados instancia_variable_get e instancia_variable_set. Sin embargo, esto rara vez es justificable y generalmente es una mala idea, ya que evitar la encapsulación tiende a causar todo tipo de estragos.
La funcionalidad principal de attr_accessor sobre los demás es la capacidad de acceder a datos de otros archivos.
Por lo tanto, normalmente tendría attr_reader o attr_writer, pero la buena noticia es que Ruby le permite combinar estos dos junto con attr_accessor. Lo considero mi método para ir porque es más completo o versátil. Además, tenga en cuenta que en Rails, esto se elimina porque lo hace por usted en la parte de atrás. En otras palabras: es mejor usar attr_acessor sobre los otros dos porque no tiene que preocuparse por ser demasiado específico, el acceso lo cubre todo. Sé que esto es más una explicación general, pero me ayudó como principiante.
git
no tiene nada que verattr_accessor
. Git es un software de control de versiones, mientras queattr_accessor
es un método en Ruby .Respuestas:
Digamos que tienes una clase
Person
.Obviamente nunca definimos el método
name
. Vamos a hacer eso.Ajá, podemos leer el nombre, pero eso no significa que podamos asignarle el nombre. Esos son dos métodos diferentes. El primero se llama lector y el segundo se llama escritor . Todavía no creamos el escritor, así que hagámoslo.
Increíble. Ahora podemos escribir y leer variables de instancia
@name
usando métodos de lector y escritor. 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.Incluso esto puede volverse repetitivo. Cuando quieras que tanto el lector como el escritor solo usen el descriptor
Funciona de la misma manera! Y adivina qué: la variable de instancia
@name
en nuestro objeto persona se establecerá como cuando lo hicimos manualmente, por lo que puedes usarla en otros métodos.Eso es. Para entender cómo
attr_reader
,attr_writer
y losattr_accessor
métodos realmente generan métodos para usted, lea otras respuestas, libros, documentos de ruby.fuente
attr_accessor
es un método llamado en la clase actual, y:name
es un parámetro que pasa a ese método. No es una sintaxis especial, es una simple llamada al método. Si@name
tuviera que darle variable, no tendría sentido, porque @name lo contendríanil
. Entonces sería como escribirattr_accessor nil
. No le está pasando una variable que necesita crear, le está pasando el nombre al que desea que se llame la variable.name
y variable@name
no son lo mismo. No los confundas. Tiene una variable de instancia@name
en su clase, y defineattr_reader :name
poder leerla desde el exterior. Sinattr_reader
no hay una manera simple de acceder@name
fuera de su clase.attr_accessor es solo un método . (El enlace debería proporcionar más información sobre cómo funciona: observe los pares de métodos generados y un tutorial le mostrará cómo usarlo).
El truco es que no
class
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 cuandoattr_accessor
se invoca el método que a su vez modifica la clase actual: recuerde el receptor implícito:self.attr_accessor
dóndeself
está el objeto de clase "abierto" en este punto.La necesidad de
attr_accessor
y amigos, es, bueno:Ruby, como Smalltalk, no permite acceder a variables de instancia fuera de los métodos 1 para ese objeto. Es decir, no se puede acceder a las variables de instancia en la
x.y
forma como es común en, por ejemplo, Java o incluso Python. En Rubyy
siempre se toma como un mensaje para enviar (o "método para llamar"). Por lo tanto, laattr_*
métodos crean contenedores que representan el@variable
acceso a la instancia a través de métodos creados dinámicamente.La repetitiva apesta
Espero que esto aclare algunos de los pequeños detalles. Feliz codificación
1 Esto no es estrictamente cierto y existen algunas "técnicas" en torno a esto , pero no hay soporte de sintaxis para el acceso de "variable de instancia pública".
fuente
attr_accessor
es (como dijo @pst) solo un método. Lo que hace es crear más métodos para ti.Entonces este código aquí:
es equivalente a este código:
Puede escribir este tipo de método usted mismo en Ruby:
fuente
attr_accessor
y ¡por fin lo encontré aquí! Aunque resolvió mi problema, pero tengo curiosidad por saber dónde (libro / documento oficial) ¿puedo encontrar un ejemplo de implementación como este?attr_accessor
es muy simple:es un atajo para:
no es más que un captador / definidor de un objeto
fuente
Básicamente, falsifican atributos de datos de acceso público, que Ruby no tiene.
fuente
Es solo un método que define los métodos getter y setter para variables de instancia. Un ejemplo de implementación sería:
fuente
Explicación simple sin ningún código
La mayoría de las respuestas anteriores usan código. Esta explicación intenta responderla sin usar ninguna, a través de una analogía / historia:
Las partes externas no pueden acceder a los secretos internos de la CIA
Imaginemos un lugar realmente secreto: la CIA. Nadie sabe lo que está sucediendo en la CIA, aparte de las personas dentro de la CIA. En otras palabras, las personas externas no pueden acceder a ninguna información en la CIA. Pero debido a que no es bueno tener una organización que es completamente secreta, cierta información se pone a disposición del mundo exterior, solo cosas que la CIA quiere que todos sepan, por supuesto: por ejemplo, el Director de la CIA, qué tan ecológico se compara este departamento a todos los demás departamentos gubernamentales, etc. Otra información: por ejemplo, quiénes son sus agentes encubiertos en Irak o Afganistán; este tipo de cosas probablemente permanecerán en secreto durante los próximos 150 años.
Si está fuera de la CIA, solo puede acceder a la información que ha puesto a disposición del público. O para usar el lenguaje de la CIA, solo puede acceder a la información que está "borrada".
La información que la CIA quiere poner a disposición del público en general fuera de la CIA se llama: atributos.
El significado de los atributos de lectura y escritura:
En el caso de la CIA, la mayoría de los atributos son "solo lectura". Esto significa que si usted es una parte externa a la CIA, puede preguntar: "¿quién es el director de la CIA?" y obtendrás una respuesta directa. Pero lo que no puede hacer con los atributos de "solo lectura" es hacer cambios en la CIA. por ejemplo, no puede hacer una llamada telefónica y de repente decidir que desea que Kim Kardashian sea el Director, o que desea que Paris Hilton sea el Comandante en Jefe.
Si los atributos le dieron acceso de "escritura", entonces podría hacer cambios si lo desea, incluso si estuviera fuera. De lo contrario, lo único que puede hacer es leer.
En otras palabras, los accesores le permiten realizar consultas o hacer cambios a organizaciones que de otro modo no dejarían entrar a personas externas, dependiendo de si los accesos son de lectura o escritura.
Los objetos dentro de una clase pueden acceder fácilmente entre sí
Exactamente lo mismo con las clases y su capacidad para acceder a variables, propiedades y métodos dentro de ellas. HTH! Cualquier pregunta, por favor pregunte y espero poder aclarar.
fuente
Si está familiarizado con el concepto OOP, debe estar familiarizado con el método getter y setter. attr_accessor hace lo mismo en Ruby.
Getter y Setter en General Way
Método Setter
Método Getter
Método Getter y Setter en Ruby
fuente
También enfrenté este problema y escribí una respuesta algo larga a esta pregunta. Ya hay algunas respuestas geniales sobre esto, pero cualquiera que busque más aclaraciones, espero que mi respuesta pueda ayudar
Método de inicialización
Initialize le permite establecer datos en una instancia de un objeto al crear la instancia en lugar de tener que establecerlos en una línea separada en su código cada vez que crea una nueva instancia de la clase.
En el código anterior, estamos configurando el nombre "Denis" utilizando el método initialize pasando a Dennis a través del parámetro en Initialize. Si quisiéramos establecer el nombre sin el método de inicialización, podríamos hacerlo así:
En el código anterior, establecemos el nombre llamando al método setter attr_accessor usando person.name, en lugar de establecer los valores al inicializar el objeto.
Ambos "métodos" de hacer este trabajo, pero inicializar nos ahorran tiempo y líneas de código.
Este es el único trabajo de inicialización. No puede llamar a initialize como método. Para obtener realmente los valores de un objeto de instancia, debe usar getters y setters (attr_reader (get), attr_writer (set) y attr_accessor (ambos)). Consulte a continuación para obtener más detalles al respecto.
Getters, Setters (attr_reader, attr_writer, attr_accessor)
Getters, attr_reader: El propósito completo de un getter es devolver el valor de una variable de instancia particular. Visite el código de muestra a continuación para obtener un desglose de esto.
En el código anterior, llama a los métodos "nombre_elemento" y "cantidad" en la instancia del elemento "ejemplo". El "pone example.item_name" y "example.quantity" devolverá (u "obtendrá") el valor de los parámetros que se pasaron al "ejemplo" y los mostrará en la pantalla.
Afortunadamente, en Ruby hay un método inherente que nos permite escribir este código de manera más sucinta; El método attr_reader. Vea el código a continuación;
Esta sintaxis funciona exactamente de la misma manera, solo que nos ahorra seis líneas de código. ¿Imagínese si tuviera 5 estados más atribuibles a la clase Item? El código se alargaría rápidamente.
Setters, attr_writer: Lo que me sorprendió al principio con los métodos setter es que, a mis ojos, parecía realizar una función idéntica al método de inicialización. A continuación explico la diferencia basada en mi comprensión;
Como se indicó anteriormente, el método de inicialización le permite establecer los valores para una instancia de un objeto tras la creación del objeto.
Pero, ¿qué sucede si desea establecer los valores más tarde, después de crear la instancia, o cambiarlos después de que se hayan inicializado? Este sería un escenario en el que usaría un método de establecimiento. Esa es la diferencia. No tiene que "establecer" un estado particular cuando está utilizando el método attr_writer inicialmente.
El siguiente código es un ejemplo del uso de un método setter para declarar el valor item_name para esta instancia de la clase Item. Tenga en cuenta que seguimos utilizando el método getter attr_reader para que podamos obtener los valores e imprimirlos en la pantalla, en caso de que desee probar el código por su cuenta.
El siguiente código es un ejemplo del uso de attr_writer para acortar nuevamente nuestro código y ahorrarnos tiempo.
El siguiente código es una reiteración del ejemplo de inicialización anterior de dónde estamos utilizando initialize para establecer el valor de objetos de item_name en la creación.
attr_accessor: realiza las funciones de attr_reader y attr_writer, ahorrándote una línea más de código.
fuente
Creo que parte de lo que confunde a los nuevos Rubyists / programadores (como yo) es:
"¿Por qué no puedo decirle a la instancia que tiene un atributo dado (por ejemplo, nombre) y darle un valor a ese atributo de una vez?"
Un poco más generalizado, pero así es como me hizo clic:
Dado:
No hemos definido Persona como algo que puede tener un nombre. o cualquier otro atributo para el caso.
Entonces si entonces:
... e intenta darles un nombre ...
Obtenemos un error porque, en Rubyland, una clase de objeto Persona no es algo asociado o capaz de tener un "nombre" ... ¡todavía!
PERO podemos usar cualquiera de los métodos dados (ver respuestas anteriores) como una forma de decir: "Una instancia de una clase Persona (
baby
) ahora puede tener un atributo llamado 'nombre', por lo tanto, no solo tenemos una forma sintáctica de obtener y establecer ese nombre, pero tiene sentido que lo hagamos ".Nuevamente, abordando esta pregunta desde un ángulo ligeramente diferente y más general, pero espero que esto ayude a la próxima instancia de la Persona de clase que encuentra su camino hacia este hilo.
fuente
En pocas palabras, definirá un setter y getter para la clase.
Tenga en cuenta que
Entonces
son equivalentes para definir un setter y getter para la clase.
fuente
Simplemente
attr-accessor
crea los métodosgetter
ysetter
para los atributos especificadosfuente
Otra forma de entenderlo es averiguar qué código de error elimina al tener
attr_accessor
.Ejemplo:
Los siguientes métodos están disponibles:
Los siguientes métodos arrojan un error:
owner
ybalance
no son, técnicamente, un método , sino un atributo. La clase BankAccount no tienedef owner
ydef balance
. Si es así, puede usar los dos comandos a continuación. Pero esos dos métodos no están ahí. Sin embargo, puede acceder a los atributos como si tuviera acceso a un método a través deattr_accessor
!! De ahí la palabraattr_accessor
. Atributo. Accesor Accede a atributos como accedería a un método.Agregar le
attr_accessor :balance, :owner
permite leer y escribirbalance
yowner
"método". Ahora puede usar los últimos 2 métodos.fuente
Define un atributo con nombre para este módulo, donde el nombre es symbol.id2name, creando una variable de instancia (@name) y un método de acceso correspondiente para leerlo. También crea un método llamado nombre = para establecer el atributo.
fuente
Para resumir un atributo, el descriptor de acceso attr_accessor le ofrece dos métodos gratuitos.
Como en Java, se llaman getters y setters.
Muchas respuestas han mostrado buenos ejemplos, así que voy a ser breve.
#the_attribute
y
# the_attribute =
En los viejos documentos de ruby, una etiqueta hash # significa un método. También podría incluir un prefijo de nombre de clase ... MyClass # my_method
fuente
Soy nuevo en Ruby y tuve que lidiar con la comprensión de la siguiente rareza. Podría ayudar a alguien más en el futuro. Al final es como se mencionó anteriormente, donde 2 funciones (def myvar, def myvar =) ambas se obtienen implícitamente para acceder a @myvar, pero estos métodos pueden anularse mediante declaraciones locales.
fuente
Atributos y métodos de acceso
Los atributos son componentes de clase a los que se puede acceder desde fuera del objeto. Se conocen como propiedades en muchos otros lenguajes de programación. Se puede acceder a sus valores utilizando la "notación de puntos", como en object_name.attribute_name. A diferencia de Python y algunos otros lenguajes, Ruby no permite acceder a variables de instancia directamente desde fuera del objeto.
En el ejemplo anterior, c es una instancia (objeto) de la clase Car. Intentamos sin éxito leer el valor de la variable de instancia de ruedas desde fuera del objeto. Lo que sucedió es que Ruby intentó llamar a un método llamado ruedas dentro del objeto c, pero no se definió dicho método. En resumen, object_name.attribute_name intenta llamar a un método llamado attribute_name dentro del objeto. Para acceder al valor de la variable ruedas desde el exterior, necesitamos implementar un método de instancia con ese nombre, que devolverá el valor de esa variable cuando se llame. Eso se llama un método de acceso. En el contexto general de programación, la forma habitual de acceder a una variable de instancia desde fuera del objeto es implementar métodos de acceso, también conocidos como métodos getter y setter.
En el siguiente ejemplo, hemos agregado métodos getter y setter a la clase Car para acceder a las variables de las ruedas desde fuera del objeto. Esta no es la "forma Ruby" de definir captadores y establecedores; solo sirve para ilustrar lo que hacen los métodos getter y setter.
El ejemplo anterior funciona y un código similar se usa comúnmente para crear métodos getter y setter en otros idiomas. Sin embargo, Ruby proporciona una forma más simple de hacer esto: tres métodos integrados llamados attr_reader, attr_writer y attr_acessor. El método attr_reader hace que una variable de instancia sea legible desde el exterior, attr_writer la hace escribible y attr_acessor la hace legible y escribible.
El ejemplo anterior se puede reescribir así.
En el ejemplo anterior, el atributo de ruedas será legible y escribible desde fuera del objeto. Si en lugar de attr_accessor, usáramos attr_reader, sería de solo lectura. Si usáramos attr_writer, sería de solo escritura. Esos tres métodos no son getters y setters en sí mismos, pero, cuando se los llama, crean métodos getter y setter para nosotros. Son métodos que generan dinámicamente (mediante programación) otros métodos; Eso se llama metaprogramación.
El primer ejemplo (más largo), que no emplea los métodos integrados de Ruby, solo debe usarse cuando se requiere código adicional en los métodos getter y setter. Por ejemplo, un método de establecimiento puede necesitar validar datos o hacer algún cálculo antes de asignar un valor a una variable de instancia.
Es posible acceder (leer y escribir) variables de instancia desde fuera del objeto, utilizando los métodos incorporados instancia_variable_get e instancia_variable_set. Sin embargo, esto rara vez es justificable y generalmente es una mala idea, ya que evitar la encapsulación tiende a causar todo tipo de estragos.
fuente
Hmmm Muchas buenas respuestas. Aquí están mis pocos centavos.
attr_accessor
es un método simple que nos ayuda a limpiar ( SECAR ) los métodos repetitivosgetter and setter
.Para que podamos centrarnos más en escribir la lógica empresarial y no preocuparnos por los creadores y captadores.
fuente
La funcionalidad principal de attr_accessor sobre los demás es la capacidad de acceder a datos de otros archivos.
Por lo tanto, normalmente tendría attr_reader o attr_writer, pero la buena noticia es que Ruby le permite combinar estos dos junto con attr_accessor. Lo considero mi método para ir porque es más completo o versátil. Además, tenga en cuenta que en Rails, esto se elimina porque lo hace por usted en la parte de atrás. En otras palabras: es mejor usar attr_acessor sobre los otros dos porque no tiene que preocuparse por ser demasiado específico, el acceso lo cubre todo. Sé que esto es más una explicación general, pero me ayudó como principiante.
Espero que esto haya ayudado!
fuente