ruby - Intermediar attr_accessor y un método de inicialización en una clase
initialization (4)
Veo código como:
class Person
def initialize(name)
@name = name
end
end
Entiendo que esto me permite hacer cosas como person = Person.new
y usar @name
en otros lugares de mi clase como otros métodos. Entonces, vi un código como:
class Person
attr_accessor :name
end
...
person = Person.new
person.name = "David"
Estoy solo en una pérdida con estos dos métodos de malla. ¿Cuáles son los usos particulares de def initialize(name)
? Supongo que attr_accessor
me permite leer y escribir. Eso implica que son dos métodos separados. ¿Sí? ¿Quiere aclaraciones sobre la def initialize
y attr_accessor
y cómo se attr_accessor
.
A diferencia de C ++, las variables de instancia de Java en Ruby son privadas por defecto (parcialmente, ya que se puede acceder a ellas usando a.instance_variable_get: @x)
p.ej:
class Dda
def initialize task
@task = task
@done = false
end
end
item = Dda.new "Jogging" # This would call the initializer and task = Jogging would
be set for item
item.task # would give error as their is no function named task to access the instance
variable.
Aunque hemos establecido el valor en item, no podremos hacer nada con él ya que las variables de instancia son privadas en ruby. código para getter:
def task
@task
end
#for getter
def task=task
@task = task
end
El uso de getter garantizaría que item.task devuelva su valor Y el uso de setter nos brinda la flexibilidad de proporcionar valores a las variables de instancia en cualquier momento.
Aquí está la respuesta que buscas Classes and methods
. Léelo cuidadosamente.
Aquí hay una buena documentación del enlace:
Clases y metodos
Ahora estamos listos para crear nuestra propia clase de direcciones. Vamos a empezar simple. Comencemos con una dirección que solo contenga el campo "calle".
Así es como se define una clase:
class Address
def initialize(street)
@street = street
end
end
Vamos a pasar por esto:
La palabra clave de clase define una clase.
Al definir un método dentro de esta clase, lo estamos asociando con esta clase.
El método de inicialización es lo que realmente construye la estructura de datos. Cada clase debe contener un método de inicialización.
@street es una variable de objeto. Similar a las claves de un hash. El signo @ distingue a @street como una variable de objeto. Cada vez que cree un objeto de la dirección de clase, este objeto contendrá una variable @street.
Usemos esta clase para crear un objeto de dirección.
address = Addres.new("23 St George St.")
Eso es. La dirección ahora es un objeto de la clase Dirección Leer los datos en un objeto
Supongamos que queremos leer los datos en el objeto de dirección. Para hacer esto, necesitamos escribir un método que devuelva estos datos:
class Address
def initialize(street)
@street = street
end
# Just return @street
def street
@street
end
end
Ahora el método Dirección calle # le permite leer la calle de la dirección. En irb:
>> address.street
=> "23 St George St."
Una propiedad de un objeto, que es visible afuera, se llama un atributo. En este caso, la calle es un atributo. En particular, es un atributo legible. Debido a que este tipo de atributo es muy común, Ruby le ofrece un acceso directo a través de la palabra clave attr_reader:
class Address
attr_reader :street
def initialize(street)
@street = street
end
end
Cambiando los datos en un objeto
También podemos definir un método para cambiar los datos en un objeto.
class Address
attr_reader :street
def initialize(street)
@street = street
end
def street=(street)
@street = street
end
end
Ruby es bastante inteligente en su uso del método street =
`address.street = "45 Main St`."
Fíjate que puedes poner espacios entre la calle y =. Ahora que podemos cambiar los datos de la dirección, podemos simplificar el método de inicialización y hacer que simplemente ajuste la calle a la cadena vacía "".
class Address
attr_reader :street
def initialize
@street = ""
end
def street=(street)
@street = street
end
end
address = Address.new
address.street = "23 St George St."
Esto puede no parecer una simplificación, pero cuando agregamos los campos de ciudad, estado y código postal, y más métodos, esto hará que la definición de clase sea un poco más simple.
Ahora, la calle es también un atributo escribible. Como antes, puede declararlo como tal con attr_writer:
class Address
attr_reader :street
attr_writer :street
def initialize
@street = ""
end
end
Acceso a datos
Muy a menudo, tienes atributos que son tanto legibles como de escritura. Ruby te permite agruparlos con attr_accessor. Supongo que estos se llamarían "atributos accesibles", pero nunca los he visto llamarse así.
class Address
attr_accessor :street
def initialize
@street = ""
end
end
Con este conocimiento, ahora es fácil definir la estructura completa de la libreta de direcciones. Como resultado, attr_accessor y amigos todos aceptan múltiples argumentos.
class Address
attr_accessor :street, :city, :state, :zip
def initialize
@street = @city = @state = @zip = ""
end
end
Creo que consideras initialize
como un constructor. Para ser precisos, no lo es. El constructor predeterminado es el new
método en la clase, e initialize
es llamado por ese método. Si no define initialize
, aún puede crear un objeto con new
porque initialize
no es el propio constructor. En ese caso, la initialize
defecto no hace nada. Si define initialize
, se llama justo después de la creación del objeto.
La declaración @foo = ...
y attr_accessor :foo
son diferentes. El primero asigna un valor a la variable de instancia @foo
, mientras que el segundo le permite acceder a @foo
través de los métodos foo
y foo=
. Sin este último, todavía puede acceder a @foo
describiéndolo directamente.
initialize
y attr_accessor
no tienen nada que ver entre sí. attr_accessor :name
crea un par de métodos:
def name
@name
end
def name=(val)
@name = val
end
Si desea establecer un nombre al crear un objeto, puede hacerlo en el inicializador:
def initialize(name)
@name = name
# or
# self.name = name
end
Pero no tienes que hacer eso. Puede establecer el nombre más tarde, después de la creación.
p = Person.new
p.name = "David"
puts p.name # >> "David"