¿Qué es attr_accessor en Ruby?


1024

Me está costando entender attr_accessoren Ruby .
¿Alguien puede explicarme esto?



1
¿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.

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

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

class Person
  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

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 @nameen nuestro objeto persona se establecerá como cuando lo hicimos manualmente, por lo que puedes 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 attr_reader, attr_writery los attr_accessormétodos realmente generan métodos para usted, lea otras respuestas, libros, documentos de ruby.


46
@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:

  1. 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.

  2. 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í:

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

Puede escribir este tipo de método usted 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

3
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
end

def foo
  @foo
end

no es más que un captador / definidor de un objeto


10
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.


44
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:

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

¡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

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"

2
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.

class Person

  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" 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í:

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

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, 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;

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

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 nuevamente nuestro código y ahorrarnos tiempo.

class Item

attr_reader :item_name
attr_writer :item_name

end

item = Item.new
puts item.item_name = "TV"

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.

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, ahorrándote una línea más de código.


10

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:

class Person
end

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.


7

En pocas palabras, definirá un setter y getter 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

Entonces

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

son equivalentes para definir un setter y getter para la clase.


5

Simplemente attr-accessorcrea los métodos gettery setterpara los atributos especificados


5

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 un error:

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

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.

$ bankie.balance
$ bankie.owner

2

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=]

1

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


1

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.

class Foo
  attr_accessor 'myvar'
  def initialize
    @myvar = "A"
    myvar = "B"
    puts @myvar # A
    puts myvar # B - myvar declared above overrides myvar method
  end

  def 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 # C
  end
end

0

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.

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ó 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.

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 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í.

class Car
  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.


-2

Hmmm Muchas buenas respuestas. Aquí están mis pocos centavos.

  • attr_accessores 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.


-3

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!

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.