tutorial sirve rails que para documentacion descargar ruby

sirve - ruby tutorial



¿Qué es attr_accessor en ruby? (18)

Estoy teniendo dificultades para entender attr_accessor en Ruby. ¿Puede alguien explicarme esto?


Atributos y métodos de acceso

Los atributos son componentes de clase a los que se puede acceder desde fuera del objeto. Son conocidos 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 las variables de instancia directamente desde fuera del objeto.

class Car def initialize @wheels = 4 # This is an instance variable end end 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ó tal 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 de las 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 de programación general, 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 de obtención y establecimiento. Un captador permite que el valor de una variable definida dentro de una clase se lea desde el exterior y un configurador permite que se escriba desde el exterior.

En el siguiente ejemplo, hemos agregado métodos de captador y definidor a la clase Coche para acceder a la variable de las ruedas desde fuera del objeto. Esta no es la "forma de Ruby" de definir a los getters y setters; solo sirve para ilustrar lo que hacen los métodos de captador y definidor.

class Car def wheels # getter method @wheels end def wheels=(val) # setter method @wheels = val end end 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 de obtención y establecimiento en otros idiomas. Sin embargo, Ruby proporciona una forma más sencilla de hacer esto: tres métodos incorporados 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 hace que se pueda escribir, y attr_acessor lo hace legible y se puede escribir.

El ejemplo anterior se puede reescribir así.

class Car attr_accessor :wheels end f = Car.new f.wheels = 4 f.wheels # Output: => 4

En el ejemplo anterior, el atributo ruedas se podrá leer y escribir desde fuera del objeto. Si en lugar de attr_accessor, usáramos attr_reader, sería de solo lectura. Si utilizamos attr_writer, sería de solo escritura. Esos tres métodos no son captadores y definidores en sí mismos, sino que, cuando se les llama, crean métodos para ellos. Son métodos que dinámicamente (programáticamente) generan otros métodos; Eso se llama metaprogramación.

El primer ejemplo (más largo), que no emplea los métodos incorporados de Ruby, solo debe usarse cuando se requiere un código adicional en los métodos de obtención y configuración. 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 instance_variable_get y instance_variable_set. Sin embargo, esto rara vez es justificable y, por lo general, es una mala idea, ya que el hecho de evitar la encapsulación tiende a causar todo tipo de estragos.


Básicamente, falsifican atributos de datos de acceso público, que Ruby no tiene.


Creo que parte de lo que confunde a los nuevos Rubyists / programadores (como yo) es:

"¿Por qué no puedo simplemente decirle a la instancia que tiene un atributo determinado (por ejemplo, nombre) y darle a ese atributo un valor de una sola vez?"

Un poco más generalizado, pero así es como me hizo clic:

Dado:

class Person end

No hemos definido a Persona como algo que puede tener un nombre o cualquier otro atributo para esa materia.

Así que si nosotros entonces:

baby = Person.new

... y tratar de darles un nombre ...

baby.name = "Ruth"

Recibimos 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 manera de decir: "Una instancia de una clase de 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 para nosotros hacerlo ".

Nuevamente, abordar esta pregunta desde un ángulo ligeramente diferente y más general, pero espero que esto ayude a la próxima instancia de la clase Persona que encuentre su camino hacia este hilo.


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.

module Mod attr_accessor(:one, :two) end Mod.instance_methods.sort #=> [:one, :one=, :two, :two=]


Digamos que tienes una Person clase.

class Person end person = Person.new person.name # => no method error

Obviamente nunca definimos el name método. 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 segundo se llama escritor . No creamos al escritor todavía, así que hagamos eso.

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 usando métodos de lector y escritor. Excepto, 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 quiera que tanto el lector como el escritor solo utilicen accessor!

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 de persona se establecerá como cuando lo hicimos manualmente, para que puedas usarla 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. Para entender cómo los attr_reader , attr_writer y attr_accessor realmente generan métodos para usted, lea otras respuestas, libros, documentos ruby.


En pocas palabras, definirá un definidor y un captador para la clase.

Tenga en cuenta que

attr_reader :v is equivalant to def v @v end attr_writer :v is equivalant to def v=(value) @v=value end

Asi que

attr_accessor :v which means attr_reader :v; attr_writer :v

son equivalentes para definir un colocador y un captador para la clase.


Es solo un método que define los métodos getter y setter para las variables de instancia. Una implementación de ejemplo sería:

def self.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 setter end end


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 repetidores de getter and setter .

  • Para que podamos centrarnos más en escribir lógica de negocios y no preocuparnos por los instaladores y captadores.


La funcionalidad principal de attr_accessor sobre los otros es la capacidad de acceder a datos de otros archivos.
Por lo general, tendría attr_reader o attr_writer, pero la buena noticia es que Ruby le permite combinar estos dos juntos con attr_accessor. Lo considero como mi método de ir porque es más completo o versátil. Además, mira con atención que en Rails, esto se elimina porque lo hace por ti en el back-end. En otras palabras, es mejor usar attr_acessor sobre los otros dos porque no tiene que preocuparse por ser específico, el descriptor de acceso lo cubre todo. Sé que esto es más una explicación general pero me ayudó como principiante.

Espero que esto haya ayudado!


La mayoría de las respuestas anteriores utilizan código. Esta explicación intenta responderla sin usar ningún código:

Explicación vía analogía

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 como no es bueno tener una organización que sea completamente secreta, cierta información está disponible para el mundo exterior, solo las cosas que la CIA quiere que todos conozcan, por ejemplo: el Director de la CIA, qué tan amigable para el medio ambiente es 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 se mantendrá 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 denomina 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 ajena 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 decide 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 afuera. De lo contrario, lo único que puedes hacer es leer.

    En otras palabras, los accesores le permiten realizar consultas, o realizar cambios, a organizaciones que de otro modo no permiten el acceso de personas externas, según si los accesores son de acceso de lectura o de 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 y preguntarle si quiere tomar una cerveza con el informante local de Kabul después del trabajo. 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.


Otra forma de entenderlo es averiguar qué código de error elimina al tener attr_accessor .

Ejemplo:

class BankAccount def initialize( account_owner ) @owner = account_owner @balance = 0 end def deposit( amount ) @balance = @balance + amount end def withdraw( amount ) @balance = @balance - amount end end

Los siguientes métodos están disponibles:

$ bankie = BankAccout.new("Iggy") $ bankie $ bankie.deposit(100) $ bankie.withdraw(5)

Los siguientes métodos arrojan error:

$ bankie.owner #undefined method `owner''... $ bankie.balance #undefined method `balance''...

owner y el balance no son, técnicamente, un método , sino un atributo. La clase BankAccount no tiene def owner def balance y def balance . Si lo hace, entonces 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 palabra attr_accessor . Atributo. Accesorio Accede a atributos como usted accedería a un método.

Agregando attr_accessor :balance, :owner permite leer y escribir balance y el "método" de owner . Ahora puedes usar los 2 últimos métodos.

$ bankie.balance $ bankie.owner


Para resumir, un atributo accessor aka attr_accessor le da dos métodos libres.

Como en Java se les llama getters y setters.

Muchas respuestas han mostrado buenos ejemplos, así que seré breve.

#el_atributo

y

# the_attribute =

En los documentos antiguos de ruby, una etiqueta hash # significa un método. También podría incluir un prefijo de nombre de clase ... MyClass # my_method


Si está familiarizado con el concepto OOP, debe estar familiarizado con el método de obtención y configuración. attr_accessor hace lo mismo en Ruby.

Getter y Setter en general.

class Person def name @name end def name=(str) @name = str end end person = Person.new person.name = ''Eshaan'' person.name # => "Eshaan"

Método Setter

def name=(val) @name = val end

Método getter

def name @name end

Método Getter y Setter en Ruby.

class Person attr_accessor :name end person = Person.new person.name = "Eshaan" person.name # => "Eshaan"


Simplemente attr-accessor crea los métodos getter y setter para los atributos especificados


También enfrenté este problema y escribí una respuesta bastante 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

Inicializar le permite establecer datos en una instancia de un objeto al crear la instancia en lugar de tener que configurarlos en una línea separada en su código cada vez que cree una nueva instancia de la clase.

class Person attr_accessor :name def initialize(name) @name = name end def greeting "Hello #{@name}" end end person = Person.new("Denis") puts person.greeting

En el código anterior, estamos configurando el nombre "Denis" usando el método de inicialización pasando a Dennis a través del parámetro en Inicializar. Si quisiéramos establecer el nombre sin el método de inicialización, podríamos hacerlo así:

class Person attr_accessor :name # def initialize(name) # @name = name # end def greeting "Hello #{name}" end end person = Person.new person.name = "Dennis" puts person.greeting

En el código anterior, establecemos el nombre invocando el método de establecimiento attr_accessor usando person.name, en lugar de establecer los valores al inicializar el objeto.

Ambos "métodos" de hacer este trabajo, pero la inicialización nos ahorra tiempo y líneas de código.

Este es el único trabajo de inicializar. No se puede llamar al inicializar como método. Para obtener realmente los valores de un objeto de instancia, debe usar los métodos de obtención y configuración (attr_reader (get), attr_writer (set) y attr_accessor (ambos)). Vea a continuación para más detalles sobre esos.

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 sobre esto.

class Item def initialize(item_name, quantity) @item_name = item_name @quantity = quantity end def item_name @item_name end def quantity @quantity end end example = Item.new("TV",2) puts example.item_name puts example.quantity

En el código anterior, está llamando a los métodos "item_name" y "cantidad" en la instancia del artículo "ejemplo". Los valores "poner example.item_name" y "example.quantity" devolverán (u "obtendrán") el valor de los parámetros que se pasaron al "ejemplo" y los mostrarán en la pantalla.

Por suerte, 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 de abajo;

class Item attr_reader :item_name, :quantity def initialize(item_name, quantity) @item_name = item_name @quantity = quantity end end item = Item.new("TV",2) puts item.item_name puts item.quantity

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 de artículo? El código se haría largo rápidamente.

Setters, attr_writer: Lo que me sorprendió al principio con los métodos de 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 en función de mi comprensión;

Como se indicó anteriormente, el método de inicialización le permite establecer los valores para una instancia de un objeto en la creación del objeto.

Pero, ¿qué sucede si desea establecer los valores más adelante, después de crear la instancia, o cambiarlos después de que se hayan inicializado? Este sería un escenario en el que utilizarías 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 código a continuación es un ejemplo del uso de un método de establecimiento para declarar el valor item_name para esta instancia de la clase de artículo. Tenga en cuenta que continuamos 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.

class Item attr_reader :item_name def item_name=(str) @item_name = (str) end end

El siguiente código es un ejemplo del uso de attr_writer para acortar una vez más nuestro código y ahorrar tiempo.

class Item attr_reader :item_name attr_writer :item_name end item = Item.new puts item.item_name = "TV"

El código a continuación es una reiteración del ejemplo de inicialización anterior de donde estamos usando inicializar para establecer el valor de los objetos de item_name en el momento de la creación.

class Item attr_reader :item_name def initialize(item_name) @item_name = item_name end end item = Item.new("TV") puts item.item_name

attr_accessor: realiza las funciones de attr_reader y attr_writer, lo que le ahorra una línea más de código.


attr_accessor es solo un método . (El enlace debe proporcionar más información acerca de cómo funciona: observe los pares de métodos generados y un tutorial le mostrará cómo usarlo).

El truco es que la class 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 se invoca el método attr_accessor 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:

  1. Ruby, como Smalltalk, no permite el acceso a las 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 forma xy como es común en, por ejemplo, Java o incluso Python. En Ruby y siempre se toma como un mensaje para enviar (o "método para llamar"). Por lo tanto, los métodos attr_* crean envolturas que representan la instancia del acceso @variable a través de métodos creados dinámicamente.

  2. Caldera chupa

Espero que esto aclare algunos de los pequeños detalles. Feliz codificacion

1 Esto no es estrictamente cierto y hay algunas "técnicas" alrededor de esto , pero no hay soporte de sintaxis para el acceso de "variable de instancia pública".


attr_accessor es (como se indica en @pst) solo un método. Lo que hace es crear más métodos para ti.

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


attr_accessor es muy simple:

attr_accessor :foo

es un atajo para:

def foo=(val) @foo = val end def foo @foo end

no es nada más que un captador / definidor para un objeto