Attr_accessor funciona da mesma maneira no Git? Estou descobrindo que alguns tutoriais não explicam o suficiente e outros assumem conhecimento prévio.
Angelfirenze
10
@Angelfirenze, gitnão tem nada a ver com attr_accessor. Git é um software de controle de versão, enquanto que attr_accessoré um método em Ruby .
Uzbekjon
Respostas:
2360
Digamos que você tenha uma aula Person.
classPersonend
person =Person.new
person.name # => no method error
Obviamente, nunca definimos método name. Vamos fazer isso.
classPersondef name
@name# simply returning an instance variable @nameendend
person =Person.new
person.name # => nil
person.name ="Dennis"# => no method error
Ah, podemos ler o nome, mas isso não significa que podemos atribuir o nome. Esses são dois métodos diferentes. O primeiro é chamado de leitor e o último é chamado de escritor . Ainda não criamos o escritor, então vamos fazer isso.
classPersondef name
@nameenddef name=(str)@name= str
endend
person =Person.new
person.name ='Dennis'
person.name # => "Dennis"
Impressionante. Agora podemos escrever e ler variáveis de instância @nameusando métodos reader e writer. Exceto que isso é feito com tanta frequência, por que perder tempo escrevendo esses métodos sempre? Nós podemos fazer isso mais fácil.
classPerson
attr_reader :name
attr_writer :name
end
Mesmo isso pode se tornar repetitivo. Quando você quiser tanto leitor quanto escritor, use o acessador!
classPerson
attr_accessor :name
end
person =Person.new
person.name ="Dennis"
person.name # => "Dennis"
Funciona da mesma maneira! E adivinhe: a variável de instância @nameem nosso objeto pessoal será definida como quando a fizemos manualmente, para que você possa usá-la em outros métodos.
É isso aí. Para entender como attr_reader, attr_writere attr_accessormétodos realmente geram métodos para você, leia outras respostas, livros, documentos em ruby.
@hakunin - obrigado por essa resposta clara. O que está faltando para mim é por que a sintaxe Ruby sugere dois pontos ':' para as variáveis de instância na instrução attr_ *? Parece que seria mais fácil usar a mesma sintaxe '@' usada em outros lugares da classe para se referir à variável.
Será
207
@WilliamSmith Para responder à sua pergunta, você precisa entender que attr_accessoré um método chamado na classe atual e :nameé um parâmetro que você passa para esse método. Não é uma sintaxe especial, é uma chamada de método simples. Se você desse uma @namevariável, não faria sentido, porque @name conteria nil. Então seria como escrever attr_accessor nil. Você não está passando uma variável que ela precisa criar, está passando o nome que deseja que a variável seja chamada.
Max Chernyak
23
@hakunin - Isso faz total sentido. Hoje eu aprendi que o ruby está na verdade 'rodando' enquanto analisa um arquivo e que toda declaração e expressão é realmente uma chamada de método em algum objeto. Incluindo attr_accessor. Muito útil.
Será
52
Rails usado por 3 anos, nunca soube disso. Vergonha
Sean Xiao
5
@ Buminda sim, mas método namee variável @namenão são a mesma coisa. Não os confunda. Você tem uma variável de instância @nameem sua classe e define attr_reader :namepara poder lê-la de fora. Sem, attr_readernão há uma maneira simples de acessar @namefora da sua turma.
Max Chernyak
127
attr_accessor é apenas um método . (O link deve fornecer mais informações sobre como ele funciona - observe os pares de métodos gerados e um tutorial deve mostrar como usá-lo.)
O truque é que nãoclass é uma definição em Ruby (é "apenas uma definição" em linguagens como C ++ e Java), mas é uma expressão que avalia . É durante essa avaliação quando o attr_accessormétodo é chamado, que por sua vez modifica a classe atual - lembre-se do receptor implícito:, self.attr_accessoronde selfestá o objeto de classe "aberto" neste momento.
A necessidade de attr_accessor e os amigos são:
Ruby, como Smalltalk, não permite que variáveis de instância sejam acessadas fora dos métodos 1 para esse objeto. Ou seja, as variáveis de instância não podem ser acessadas no x.yformulário, como é comum, por exemplo, Java ou mesmo Python. Em Ruby yé sempre tomada como uma mensagem para enviar (ou "método para chamar"). Assim, os attr_*métodos criam wrappers que @variableacessam a instância por meio de métodos criados dinamicamente.
Boilerplate é uma merda
Espero que isso esclareça alguns dos pequenos detalhes. Feliz codificação.
1 Isso não é estritamente verdadeiro e existem algumas "técnicas" em torno disso , mas não há suporte à sintaxe para acesso à "variável de instância pública".
Quando você diz que attr_accessor é "apenas um método", eu entendi. Mas como é chamada a sintaxe usada para chamar esse método? Estou tendo problemas para encontrar a seção na documentação do ruby que fala sobre sintaxe como some_method: name => "qualquer coisa",: notherName,: etc
BT
68
attr_accessoré (como @pst afirmou) apenas um método. O que ele faz é criar mais métodos para você.
Portanto, este código aqui:
classFoo
attr_accessor :bar
end
é equivalente a este código:
classFoodef bar
@barenddef bar=( new_value )@bar= new_value
endend
Você pode escrever esse tipo de método em 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 é um ótimo exemplo de onde a metaprogramação é usada mesmo nos cenários mais iniciantes. Muito agradável.
John Simon
2
Eu estava procurando por um esboço de implementação attr_accessore finalmente encontrei aqui! Embora tenha resolvido meu problema, mas estou curioso para saber onde (livro / documento oficial) posso encontrar um exemplo de implementação como este?
Wasif Hossain
40
attr_accessor é muito simples:
attr_accessor :foo
é um atalho para:
def foo=(val)@foo= val
enddef foo
@fooend
nada mais é do que um getter / setter para um objeto
sua resposta está bem. 'Atalho' significa "uma rota alternativa mais curta", de acordo com o meu dicionário, não "açúcar de sintaxe" ou "macro interpretada pelo intérprete".
bowsersenior
25
Basicamente, eles falsificam atributos de dados acessíveis ao público, que Ruby não possui.
Embora esse comentário não seja totalmente útil, é verdade. Destaca o fato de que os atributos de dados públicos não existem fora dos métodos "get" no Ruby, que são informações realmente úteis para alguém que tenta aprender o idioma.
quer
3
Isso realmente não deve ser rebaixado. Como um cara não-Ruby, tentando descobrir isso, essa resposta é muito útil!
19413 Brad
1
Concordado, parece muito semelhante ao nome do C # {get; set;}
David Miler
17
É apenas um método que define métodos getter e setter para variáveis de instância. Um exemplo de implementação seria:
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
Este foi um trecho de código realmente útil para resolver outra questão relacionada à metaprogramação.
alexventuraio 30/03
15
Explicação simples sem qualquer código
A maioria das respostas acima usa código. Esta explicação tenta responder sem usar nenhuma, por meio de uma analogia / história:
As partes externas não podem acessar segredos internos da CIA
Vamos imaginar um lugar realmente secreto: a CIA. Ninguém sabe o que está acontecendo na CIA além das pessoas dentro da CIA. Em outras palavras, pessoas externas não podem acessar nenhuma informação na CIA. Mas como não é bom ter uma organização que é completamente secreta, certas informações são disponibilizadas para o mundo exterior - apenas as coisas que a CIA deseja que todos saibam, é claro: por exemplo, o diretor da CIA, como esse departamento é ecológico para todos os outros departamentos governamentais etc. Outras informações: por exemplo, quem são seus agentes secretos no Iraque ou no Afeganistão - esse tipo de coisa provavelmente permanecerá em segredo pelos próximos 150 anos.
Se você estiver fora da CIA, poderá acessar apenas as informações disponibilizadas ao público. Ou, para usar a linguagem da CIA, você pode acessar apenas as informações "limpas".
As informações que a CIA deseja disponibilizar ao público em geral fora da CIA são denominadas: atributos.
O significado dos atributos de leitura e gravação:
No caso da CIA, a maioria dos atributos é "somente leitura". Isso significa que, se você é uma parte externa à CIA, pode perguntar: "quem é o diretor da CIA?" e você receberá uma resposta direta. Mas o que você não pode fazer com os atributos "somente leitura" é fazer alterações na CIA. por exemplo, você não pode fazer uma ligação e decidir subitamente que deseja que Kim Kardashian seja o diretor ou que Paris Hilton seja o comandante em chefe.
Se os atributos fornecerem acesso "de gravação", você poderá fazer alterações, se desejar, mesmo se estiver fora. Caso contrário, a única coisa que você pode fazer é ler.
Em outras palavras, os acessadores permitem que você faça consultas ou faça alterações em organizações que de outra forma não permitem a entrada de pessoas externas, dependendo de os acessadores serem acessadores de leitura ou gravação.
Objetos dentro de uma classe podem acessar-se facilmente
Por outro lado, se você já estava dentro da CIA, poderia facilmente chamar seu agente da CIA em Cabul, porque essas informações são facilmente acessíveis, desde que você já esteja dentro. Mas se você estiver fora da CIA, você simplesmente não terá acesso: não poderá saber quem eles são (acesso de leitura) e não poderá alterar a missão deles (acesso de gravação).
Exatamente o mesmo com as classes e sua capacidade de acessar variáveis, propriedades e métodos dentro delas. HTH! Qualquer dúvida, por favor, pergunte e espero que eu possa esclarecer.
Sua explicação faz sentido! +1 Desculpe, você tem certeza de que a expressão "informações que são limpas pela CIA está correta?"
kouty 11/12/16
existem vários níveis de "liberação" na CIA: por exemplo, Top Secret (ninguém além do Prez) ou confiança pública (todos podem ler essa informação). A CIA realmente fornece muitos fatos muito interessantes!
BKSpurgeon
Você merece o voto positivo apenas pelos exemplos de Kardashian e Paris Hilton :) Eu pensei que era ruim o suficiente com Trump para Presidente, imagine aqueles dois encarregados!
Rmcsharry 24/03/19
Sim! É disso que precisamos, StackOverflow sem código! :-)
Marvin
13
Se você está familiarizado com o conceito de POO, deve familiarizar-se com o método getter e setter. attr_accessor faz o mesmo em Ruby.
Getter e Setter de maneira geral
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 e Setter em Ruby
classPerson
attr_accessor :name
end
person =Person.new
person.name ="Eshaan"
person.name # => "Eshaan"
explicação perfeita! É um comportamento muito útil e pode ser substituído com muita facilidade.
Rubyrider 8/15
12
Também enfrentei esse problema e escrevi uma resposta um tanto demorada para essa pergunta. Já existem ótimas respostas sobre isso, mas quem procura mais esclarecimentos, espero que minha resposta possa ajudar
Método de inicialização
Initialize permite que você defina dados para uma instância de um objeto após a criação da instância, em vez de precisar defini-los em uma linha separada no seu código toda vez que você cria uma nova instância da classe.
classPersondef initialize(name)@name= name
enddef greeting
"Hello #{@name}"endend
person =Person.new("Denis")
puts person.greeting
No código acima, estamos definindo o nome “Denis” usando o método initialize passando Dennis pelo parâmetro em Initialize. Se quiséssemos definir o nome sem o método initialize, poderíamos fazer o seguinte:
No código acima, definimos o nome chamando o método attr_accessor setter usando person.name, em vez de definir os valores na inicialização do objeto.
Os dois "métodos" de fazer esse trabalho, mas inicializar, economizam tempo e linhas de código.
Este é o único trabalho de inicialização. Você não pode chamar a inicialização como um método. Para realmente obter os valores de um objeto de instância, você precisa usar getters e setters (attr_reader (get), attr_writer (set) e attr_accessor (ambos)). Veja abaixo mais detalhes sobre esses.
Getters, attr_reader: O objetivo inteiro de um getter é retornar o valor de uma variável de instância específica. Visite o código de exemplo abaixo para obter detalhes sobre isso.
No código acima, você está chamando os métodos "item_name" e "quantidade" na instância do item "exemplo". O “puts example.item_name” e “example.quantity” retornarão (ou “obterão”) o valor dos parâmetros que foram passados para o “exemplo” e os exibirão na tela.
Felizmente, em Ruby, existe um método inerente que nos permite escrever esse código de forma mais sucinta; o método attr_reader. Veja o código abaixo;
Essa sintaxe funciona exatamente da mesma maneira, mas nos salva seis linhas de código. Imagine se você tivesse mais 5 estados atribuíveis à classe Item? O código iria demorar muito rapidamente.
Setters, attr_writer: O que me impressionou no início com os métodos setter é que, aos meus olhos, parecia desempenhar uma função idêntica ao método inicializar. Abaixo, explico a diferença com base no meu entendimento;
Como mencionado anteriormente, o método initialize permite definir os valores para uma instância de um objeto na criação do objeto.
Mas e se você quiser definir os valores posteriormente, após a instância ter sido criada, ou alterá-los após a inicialização? Este seria um cenário em que você usaria um método setter. Essa é a diferença. Você não precisa "definir" um estado específico quando estiver usando o método attr_writer inicialmente.
O código abaixo é um exemplo de uso de um método setter para declarar o valor item_name para esta instância da classe Item. Observe que continuamos a usar o método getter attr_reader para que possamos obter os valores e imprimi-los na tela, caso você queira testar o código por conta própria.
O código abaixo é uma reiteração do exemplo de inicialização acima de onde estamos usando initialize para definir o valor dos objetos item_name na criação.
Eu acho que parte do que confunde novos rubiistas / programadores (como eu) é:
"Por que não posso simplesmente dizer à instância que ele possui algum atributo (por exemplo, nome) e atribuir um valor a esse atributo de uma só vez?"
Um pouco mais generalizado, mas foi assim que clicou para mim:
Dado:
classPersonend
Não definimos Person como algo que pode ter um nome ou qualquer outro atributo para esse assunto.
Então, se nós:
baby =Person.new
... e tente dar um nome a eles ...
baby.name ="Ruth"
Recebemos um erro porque, em Rubyland, uma classe de objeto Person não é algo associado ou capaz de ter um "nome" ... ainda!
MAS podemos usar qualquer um dos métodos fornecidos (consulte as respostas anteriores) como uma maneira de dizer: "Uma instância de uma classe Person ( baby) agora pode ter um atributo chamado 'name'; portanto, não temos apenas uma maneira sintática de obter e definindo esse nome, mas faz sentido para nós ".
Novamente, respondendo a essa pergunta de um ângulo um pouco diferente e mais geral, mas espero que isso ajude a próxima instância da classe Person que encontra seu caminho para esse segmento.
ownere balancenão são, tecnicamente, um método , mas um atributo. A classe BankAccount não possui def ownere def balance. Nesse caso, você pode usar os dois comandos abaixo. Mas esses dois métodos não estão lá. No entanto, você pode acessar atributos como se você tivesse acessar um método via attr_accessor!! Daí a palavraattr_accessor . Atributo. Accessor. Ele acessa atributos como você acessaria um método.
A adição attr_accessor :balance, :ownerpermite ler e escrever balancee owner"método". Agora você pode usar os dois últimos métodos.
Define um atributo nomeado para este módulo, em que o nome é symbol.id2name, criando uma variável de instância (@name) e um método de acesso correspondente para lê-lo. Também cria um método chamado name = para definir o atributo.
Eu sou novo no Ruby e tive que lidar apenas com a compreensão da seguinte estranheza. Pode ajudar alguém no futuro. No final, é como foi mencionado acima, onde 2 funções (def myvar, def myvar =) ficam implicitamente para acessar @myvar, mas esses métodos podem ser substituídos por declarações locais.
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
Atributos são componentes de classe que podem ser acessados de fora do objeto. Eles são conhecidos como propriedades em muitas outras linguagens de programação. Seus valores são acessíveis usando a "notação de ponto", como em object_name.attribute_name. Diferentemente do Python e de algumas outras linguagens, o Ruby não permite que variáveis da instância sejam acessadas diretamente de fora do objeto.
classCardef initialize
@wheels=4# This is an instance variableendend
c =Car.new
c.wheels # Output: NoMethodError: undefined method `wheels' for #<Car:0x00000000d43500>
No exemplo acima, c é uma instância (objeto) da classe Car. Tentamos, sem sucesso, ler o valor da variável de instância wheel de fora do objeto. O que aconteceu foi que Ruby tentou chamar um método chamado wheel dentro do objeto c, mas nenhum método foi definido. Em resumo, object_name.attribute_name tenta chamar um método chamado attribute_name dentro do objeto. Para acessar o valor da variável wheel de fora, precisamos implementar um método de instância com esse nome, que retornará o valor dessa variável quando for chamado. Isso é chamado de método acessador. No contexto geral de programação, a maneira usual de acessar uma variável de instância de fora do objeto é implementar métodos acessadores, também conhecidos como métodos getter e setter.
No exemplo a seguir, adicionamos métodos getter e setter à classe Car para acessar a variável wheel de fora do objeto. Esta não é a "maneira Ruby" de definir getters e setters; serve apenas para ilustrar o que os métodos getter e setter fazem.
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
O exemplo acima funciona e um código semelhante é comumente usado para criar métodos getter e setter em outros idiomas. No entanto, o Ruby fornece uma maneira mais simples de fazer isso: três métodos internos chamados attr_reader, attr_writer e attr_acessor. O método attr_reader torna uma variável de instância legível do lado de fora, attr_writer a torna gravável e attr_acessor a torna legível e gravável.
O exemplo acima pode ser reescrito assim.
classCar
attr_accessor :wheels
end
f =Car.new
f.wheels =4
f.wheels # Output: => 4
No exemplo acima, o atributo wheel será legível e gravável de fora do objeto. Se, em vez de attr_accessor, usamos attr_reader, seria somente leitura. Se usássemos attr_writer, seria somente gravação. Esses três métodos não são getters e setters em si mesmos, mas, quando chamados, criam métodos getter e setter para nós. São métodos que geram dinamicamente (programaticamente) outros métodos; isso é chamado de metaprogramação.
O primeiro exemplo (mais longo), que não emprega os métodos internos do Ruby, deve ser usado apenas quando código adicional for necessário nos métodos getter e setter. Por exemplo, um método setter pode precisar validar dados ou fazer algum cálculo antes de atribuir um valor a uma variável de instância.
É possível acessar (ler e escrever) variáveis de instância de fora do objeto, usando os métodos internos instance_variable_get e instance_variable_set. No entanto, isso raramente é justificável e geralmente é uma péssima idéia, já que contornar o encapsulamento tende a causar todo tipo de confusão.
A principal funcionalidade do attr_accessor sobre as outras é a capacidade de acessar dados de outros arquivos.
Então você normalmente teria attr_reader ou attr_writer, mas a boa notícia é que Ruby permite combinar esses dois com o attr_accessor. Penso nisso como o meu método de ir, porque é mais bem-arredondado ou versátil. Além disso, lembre-se de que, no Rails, isso é eliminado porque faz isso por você no back-end. Portanto, em outras palavras: é melhor usar o attr_acessor em relação aos outros dois porque não precisa se preocupar em ser específico, o acessador cobre tudo. Eu sei que essa é uma explicação mais geral, mas me ajudou como iniciante.
git
não tem nada a ver comattr_accessor
. Git é um software de controle de versão, enquanto queattr_accessor
é um método em Ruby .Respostas:
Digamos que você tenha uma aula
Person
.Obviamente, nunca definimos método
name
. Vamos fazer isso.Ah, podemos ler o nome, mas isso não significa que podemos atribuir o nome. Esses são dois métodos diferentes. O primeiro é chamado de leitor e o último é chamado de escritor . Ainda não criamos o escritor, então vamos fazer isso.
Impressionante. Agora podemos escrever e ler variáveis de instância
@name
usando métodos reader e writer. Exceto que isso é feito com tanta frequência, por que perder tempo escrevendo esses métodos sempre? Nós podemos fazer isso mais fácil.Mesmo isso pode se tornar repetitivo. Quando você quiser tanto leitor quanto escritor, use o acessador!
Funciona da mesma maneira! E adivinhe: a variável de instância
@name
em nosso objeto pessoal será definida como quando a fizemos manualmente, para que você possa usá-la em outros métodos.É isso aí. Para entender como
attr_reader
,attr_writer
eattr_accessor
métodos realmente geram métodos para você, leia outras respostas, livros, documentos em ruby.fonte
attr_accessor
é um método chamado na classe atual e:name
é um parâmetro que você passa para esse método. Não é uma sintaxe especial, é uma chamada de método simples. Se você desse uma@name
variável, não faria sentido, porque @name conterianil
. Então seria como escreverattr_accessor nil
. Você não está passando uma variável que ela precisa criar, está passando o nome que deseja que a variável seja chamada.name
e variável@name
não são a mesma coisa. Não os confunda. Você tem uma variável de instância@name
em sua classe e defineattr_reader :name
para poder lê-la de fora. Sem,attr_reader
não há uma maneira simples de acessar@name
fora da sua turma.attr_accessor é apenas um método . (O link deve fornecer mais informações sobre como ele funciona - observe os pares de métodos gerados e um tutorial deve mostrar como usá-lo.)
O truque é que não
class
é uma definição em Ruby (é "apenas uma definição" em linguagens como C ++ e Java), mas é uma expressão que avalia . É durante essa avaliação quando oattr_accessor
método é chamado, que por sua vez modifica a classe atual - lembre-se do receptor implícito:,self.attr_accessor
ondeself
está o objeto de classe "aberto" neste momento.A necessidade de
attr_accessor
e os amigos são:Ruby, como Smalltalk, não permite que variáveis de instância sejam acessadas fora dos métodos 1 para esse objeto. Ou seja, as variáveis de instância não podem ser acessadas no
x.y
formulário, como é comum, por exemplo, Java ou mesmo Python. Em Rubyy
é sempre tomada como uma mensagem para enviar (ou "método para chamar"). Assim, osattr_*
métodos criam wrappers que@variable
acessam a instância por meio de métodos criados dinamicamente.Boilerplate é uma merda
Espero que isso esclareça alguns dos pequenos detalhes. Feliz codificação.
1 Isso não é estritamente verdadeiro e existem algumas "técnicas" em torno disso , mas não há suporte à sintaxe para acesso à "variável de instância pública".
fonte
attr_accessor
é (como @pst afirmou) apenas um método. O que ele faz é criar mais métodos para você.Portanto, este código aqui:
é equivalente a este código:
Você pode escrever esse tipo de método em Ruby:
fonte
attr_accessor
e finalmente encontrei aqui! Embora tenha resolvido meu problema, mas estou curioso para saber onde (livro / documento oficial) posso encontrar um exemplo de implementação como este?attr_accessor
é muito simples:é um atalho para:
nada mais é do que um getter / setter para um objeto
fonte
Basicamente, eles falsificam atributos de dados acessíveis ao público, que Ruby não possui.
fonte
É apenas um método que define métodos getter e setter para variáveis de instância. Um exemplo de implementação seria:
fonte
Explicação simples sem qualquer código
A maioria das respostas acima usa código. Esta explicação tenta responder sem usar nenhuma, por meio de uma analogia / história:
As partes externas não podem acessar segredos internos da CIA
Vamos imaginar um lugar realmente secreto: a CIA. Ninguém sabe o que está acontecendo na CIA além das pessoas dentro da CIA. Em outras palavras, pessoas externas não podem acessar nenhuma informação na CIA. Mas como não é bom ter uma organização que é completamente secreta, certas informações são disponibilizadas para o mundo exterior - apenas as coisas que a CIA deseja que todos saibam, é claro: por exemplo, o diretor da CIA, como esse departamento é ecológico para todos os outros departamentos governamentais etc. Outras informações: por exemplo, quem são seus agentes secretos no Iraque ou no Afeganistão - esse tipo de coisa provavelmente permanecerá em segredo pelos próximos 150 anos.
Se você estiver fora da CIA, poderá acessar apenas as informações disponibilizadas ao público. Ou, para usar a linguagem da CIA, você pode acessar apenas as informações "limpas".
As informações que a CIA deseja disponibilizar ao público em geral fora da CIA são denominadas: atributos.
O significado dos atributos de leitura e gravação:
No caso da CIA, a maioria dos atributos é "somente leitura". Isso significa que, se você é uma parte externa à CIA, pode perguntar: "quem é o diretor da CIA?" e você receberá uma resposta direta. Mas o que você não pode fazer com os atributos "somente leitura" é fazer alterações na CIA. por exemplo, você não pode fazer uma ligação e decidir subitamente que deseja que Kim Kardashian seja o diretor ou que Paris Hilton seja o comandante em chefe.
Se os atributos fornecerem acesso "de gravação", você poderá fazer alterações, se desejar, mesmo se estiver fora. Caso contrário, a única coisa que você pode fazer é ler.
Em outras palavras, os acessadores permitem que você faça consultas ou faça alterações em organizações que de outra forma não permitem a entrada de pessoas externas, dependendo de os acessadores serem acessadores de leitura ou gravação.
Objetos dentro de uma classe podem acessar-se facilmente
Exatamente o mesmo com as classes e sua capacidade de acessar variáveis, propriedades e métodos dentro delas. HTH! Qualquer dúvida, por favor, pergunte e espero que eu possa esclarecer.
fonte
Se você está familiarizado com o conceito de POO, deve familiarizar-se com o método getter e setter. attr_accessor faz o mesmo em Ruby.
Getter e Setter de maneira geral
Método Setter
Método Getter
Método Getter e Setter em Ruby
fonte
Também enfrentei esse problema e escrevi uma resposta um tanto demorada para essa pergunta. Já existem ótimas respostas sobre isso, mas quem procura mais esclarecimentos, espero que minha resposta possa ajudar
Método de inicialização
Initialize permite que você defina dados para uma instância de um objeto após a criação da instância, em vez de precisar defini-los em uma linha separada no seu código toda vez que você cria uma nova instância da classe.
No código acima, estamos definindo o nome “Denis” usando o método initialize passando Dennis pelo parâmetro em Initialize. Se quiséssemos definir o nome sem o método initialize, poderíamos fazer o seguinte:
No código acima, definimos o nome chamando o método attr_accessor setter usando person.name, em vez de definir os valores na inicialização do objeto.
Os dois "métodos" de fazer esse trabalho, mas inicializar, economizam tempo e linhas de código.
Este é o único trabalho de inicialização. Você não pode chamar a inicialização como um método. Para realmente obter os valores de um objeto de instância, você precisa usar getters e setters (attr_reader (get), attr_writer (set) e attr_accessor (ambos)). Veja abaixo mais detalhes sobre esses.
Getters, Setters (attr_reader, attr_writer, attr_accessor)
Getters, attr_reader: O objetivo inteiro de um getter é retornar o valor de uma variável de instância específica. Visite o código de exemplo abaixo para obter detalhes sobre isso.
No código acima, você está chamando os métodos "item_name" e "quantidade" na instância do item "exemplo". O “puts example.item_name” e “example.quantity” retornarão (ou “obterão”) o valor dos parâmetros que foram passados para o “exemplo” e os exibirão na tela.
Felizmente, em Ruby, existe um método inerente que nos permite escrever esse código de forma mais sucinta; o método attr_reader. Veja o código abaixo;
Essa sintaxe funciona exatamente da mesma maneira, mas nos salva seis linhas de código. Imagine se você tivesse mais 5 estados atribuíveis à classe Item? O código iria demorar muito rapidamente.
Setters, attr_writer: O que me impressionou no início com os métodos setter é que, aos meus olhos, parecia desempenhar uma função idêntica ao método inicializar. Abaixo, explico a diferença com base no meu entendimento;
Como mencionado anteriormente, o método initialize permite definir os valores para uma instância de um objeto na criação do objeto.
Mas e se você quiser definir os valores posteriormente, após a instância ter sido criada, ou alterá-los após a inicialização? Este seria um cenário em que você usaria um método setter. Essa é a diferença. Você não precisa "definir" um estado específico quando estiver usando o método attr_writer inicialmente.
O código abaixo é um exemplo de uso de um método setter para declarar o valor item_name para esta instância da classe Item. Observe que continuamos a usar o método getter attr_reader para que possamos obter os valores e imprimi-los na tela, caso você queira testar o código por conta própria.
O código abaixo é um exemplo de uso do attr_writer para encurtar novamente nosso código e economizar tempo.
O código abaixo é uma reiteração do exemplo de inicialização acima de onde estamos usando initialize para definir o valor dos objetos item_name na criação.
attr_accessor: Executa as funções de attr_reader e attr_writer, economizando mais uma linha de código.
fonte
Eu acho que parte do que confunde novos rubiistas / programadores (como eu) é:
"Por que não posso simplesmente dizer à instância que ele possui algum atributo (por exemplo, nome) e atribuir um valor a esse atributo de uma só vez?"
Um pouco mais generalizado, mas foi assim que clicou para mim:
Dado:
Não definimos Person como algo que pode ter um nome ou qualquer outro atributo para esse assunto.
Então, se nós:
... e tente dar um nome a eles ...
Recebemos um erro porque, em Rubyland, uma classe de objeto Person não é algo associado ou capaz de ter um "nome" ... ainda!
MAS podemos usar qualquer um dos métodos fornecidos (consulte as respostas anteriores) como uma maneira de dizer: "Uma instância de uma classe Person (
baby
) agora pode ter um atributo chamado 'name'; portanto, não temos apenas uma maneira sintática de obter e definindo esse nome, mas faz sentido para nós ".Novamente, respondendo a essa pergunta de um ângulo um pouco diferente e mais geral, mas espero que isso ajude a próxima instância da classe Person que encontra seu caminho para esse segmento.
fonte
Simplificando, ele definirá um setter e um getter para a classe.
Observe que
assim
são equivalentes para definir um setter e um getter para a classe.
fonte
Simplesmente
attr-accessor
cria os métodosgetter
esetter
para os atributos especificadosfonte
Outra maneira de entender isso é descobrir qual código de erro ele elimina por ter
attr_accessor
.Exemplo:
Os seguintes métodos estão disponíveis:
Os seguintes métodos geram erro:
owner
ebalance
não são, tecnicamente, um método , mas um atributo. A classe BankAccount não possuidef owner
edef balance
. Nesse caso, você pode usar os dois comandos abaixo. Mas esses dois métodos não estão lá. No entanto, você pode acessar atributos como se você tivesse acessar um método viaattr_accessor
!! Daí a palavraattr_accessor
. Atributo. Accessor. Ele acessa atributos como você acessaria um método.A adição
attr_accessor :balance, :owner
permite ler e escreverbalance
eowner
"método". Agora você pode usar os dois últimos métodos.fonte
Define um atributo nomeado para este módulo, em que o nome é symbol.id2name, criando uma variável de instância (@name) e um método de acesso correspondente para lê-lo. Também cria um método chamado name = para definir o atributo.
fonte
Resumir um acessador de atributo, também conhecido como attr_accessor, oferece dois métodos gratuitos.
Como em Java, eles são chamados de getters e setters.
Muitas respostas mostraram bons exemplos, por isso vou ser breve.
#the_attribute
e
# the_attribute =
Nos documentos antigos do ruby, um hash tag # significa um método. Também pode incluir um prefixo de nome de classe ... MyClass # my_method
fonte
Eu sou novo no Ruby e tive que lidar apenas com a compreensão da seguinte estranheza. Pode ajudar alguém no futuro. No final, é como foi mencionado acima, onde 2 funções (def myvar, def myvar =) ficam implicitamente para acessar @myvar, mas esses métodos podem ser substituídos por declarações locais.
fonte
Atributos e métodos de acessador
Atributos são componentes de classe que podem ser acessados de fora do objeto. Eles são conhecidos como propriedades em muitas outras linguagens de programação. Seus valores são acessíveis usando a "notação de ponto", como em object_name.attribute_name. Diferentemente do Python e de algumas outras linguagens, o Ruby não permite que variáveis da instância sejam acessadas diretamente de fora do objeto.
No exemplo acima, c é uma instância (objeto) da classe Car. Tentamos, sem sucesso, ler o valor da variável de instância wheel de fora do objeto. O que aconteceu foi que Ruby tentou chamar um método chamado wheel dentro do objeto c, mas nenhum método foi definido. Em resumo, object_name.attribute_name tenta chamar um método chamado attribute_name dentro do objeto. Para acessar o valor da variável wheel de fora, precisamos implementar um método de instância com esse nome, que retornará o valor dessa variável quando for chamado. Isso é chamado de método acessador. No contexto geral de programação, a maneira usual de acessar uma variável de instância de fora do objeto é implementar métodos acessadores, também conhecidos como métodos getter e setter.
No exemplo a seguir, adicionamos métodos getter e setter à classe Car para acessar a variável wheel de fora do objeto. Esta não é a "maneira Ruby" de definir getters e setters; serve apenas para ilustrar o que os métodos getter e setter fazem.
O exemplo acima funciona e um código semelhante é comumente usado para criar métodos getter e setter em outros idiomas. No entanto, o Ruby fornece uma maneira mais simples de fazer isso: três métodos internos chamados attr_reader, attr_writer e attr_acessor. O método attr_reader torna uma variável de instância legível do lado de fora, attr_writer a torna gravável e attr_acessor a torna legível e gravável.
O exemplo acima pode ser reescrito assim.
No exemplo acima, o atributo wheel será legível e gravável de fora do objeto. Se, em vez de attr_accessor, usamos attr_reader, seria somente leitura. Se usássemos attr_writer, seria somente gravação. Esses três métodos não são getters e setters em si mesmos, mas, quando chamados, criam métodos getter e setter para nós. São métodos que geram dinamicamente (programaticamente) outros métodos; isso é chamado de metaprogramação.
O primeiro exemplo (mais longo), que não emprega os métodos internos do Ruby, deve ser usado apenas quando código adicional for necessário nos métodos getter e setter. Por exemplo, um método setter pode precisar validar dados ou fazer algum cálculo antes de atribuir um valor a uma variável de instância.
É possível acessar (ler e escrever) variáveis de instância de fora do objeto, usando os métodos internos instance_variable_get e instance_variable_set. No entanto, isso raramente é justificável e geralmente é uma péssima idéia, já que contornar o encapsulamento tende a causar todo tipo de confusão.
fonte
Hummm. Muitas boas respostas. Aqui estão meus poucos centavos.
attr_accessor
é um método simples que nos ajuda a limpar ( secar ) os métodos repetidosgetter and setter
.Para que possamos nos concentrar mais em escrever a lógica de negócios e não nos preocupar com os levantadores e os levantadores.
fonte
A principal funcionalidade do attr_accessor sobre as outras é a capacidade de acessar dados de outros arquivos.
Então você normalmente teria attr_reader ou attr_writer, mas a boa notícia é que Ruby permite combinar esses dois com o attr_accessor. Penso nisso como o meu método de ir, porque é mais bem-arredondado ou versátil. Além disso, lembre-se de que, no Rails, isso é eliminado porque faz isso por você no back-end. Portanto, em outras palavras: é melhor usar o attr_acessor em relação aos outros dois porque não precisa se preocupar em ser específico, o acessador cobre tudo. Eu sei que essa é uma explicação mais geral, mas me ajudou como iniciante.
Espero que isso tenha ajudado!
fonte