O que são variáveis de Ruby precedido com o dobro de sinais ( @@
)? Meu entendimento de uma variável precedida por um sinal de arroba é que ela é uma variável de instância, como esta no PHP:
Versão PHP
class Person {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Equivalente a Ruby
class Person
def set_name(name)
@name = name
end
def get_name()
@name
end
end
O que significa o dobro no sinal @@
e como ele difere de um único sinal?
@
internosself
) e não variáveis de classe (@@
). Veja a litania de razões pelas quais as respostas abaixo.Respostas:
Uma variável prefixada com
@
é uma variável de instância , enquanto uma prefixada com@@
é uma variável de classe . Confira o exemplo a seguir; sua saída está nos comentários no final dasputs
linhas:Você pode ver que
@@shared
é compartilhado entre as classes; definir o valor em uma instância de um altera o valor para todas as outras instâncias dessa classe e até mesmo classes filho, onde uma variável chamada@shared
, com um@
, não seria.[Atualizar]
Como Phrogz menciona nos comentários, é um idioma comum no Ruby rastrear dados em nível de classe com uma variável de instância na própria classe . Esse pode ser um assunto difícil de entender, e há muitas leituras adicionais sobre o assunto, mas pense nisso como modificar a
Class
classe, mas apenas a instância daClass
classe com a qual você está trabalhando. Um exemplo:Incluí o
Square
exemplo (que resultadosnil
) para demonstrar que isso pode não se comportar 100% conforme o esperado; o artigo que vinculei acima tem muitas informações adicionais sobre o assunto.Lembre-se também de que, como na maioria dos dados, você deve ser extremamente cuidadoso com as variáveis de classe em um ambiente multithread , conforme comentário de dmarkow.
fonte
ruby class << self end
bloco faz, especificamente o operador <<.class << self
ver este@
- Variável de instância de uma classe@@
- Variável de classe, também chamada como variável estática em alguns casosUma variável de classe é uma variável compartilhada entre todas as instâncias de uma classe. Isso significa que existe apenas um valor variável para todos os objetos instanciados nesta classe. Se uma instância do objeto alterar o valor da variável, esse novo valor será alterado essencialmente para todas as outras instâncias do objeto.
Outra maneira de pensar sobre as variáveis de classe é como variáveis globais no contexto de uma única classe. As variáveis de classe são declaradas prefixando o nome da variável com dois
@
caracteres (@@
). Variáveis de classe devem ser inicializadas no momento da criaçãofonte
@@
denota uma variável de classe, ou seja, pode ser herdada.Isso significa que, se você criar uma subclasse dessa classe, ela herdará a variável. Portanto, se você tiver uma classe
Vehicle
com a variável de classe@@number_of_wheels
, se criar umaclass Car < Vehicle
, ela também terá a variável de classe@@number_of_wheels
fonte
Vehicle
com a variável de classe@@number_of_wheels
, em seguida, se você criar umclass Car < Vehicle
, em seguida, ele também terá a variável de classe@@number_of_wheels
class Vehicle
com@number_of_wheels
,class Car < Vehicle
também terá uma variável de instância chamada@number_of_wheels
. A principal diferença com as variáveis de classe é que as classes têm a mesma variável, por exemplo, alterar uma altera as outras.@ e @@ nos módulos também funcionam de maneira diferente quando uma classe estende ou inclui esse módulo.
Tão dado
Então você obtém as saídas abaixo mostradas como comentários
Portanto, use @@ in modules para variáveis que você deseja que sejam comuns a todos os seus usos, e use @ in modules para variáveis que você deseja separar para cada contexto de uso.
fonte
As respostas estão parcialmente corretas porque @@ é realmente uma variável de classe que é por hierarquia de classes, o que significa que é compartilhada por uma classe, suas instâncias e suas classes descendentes e suas instâncias.
Isso produzirá
Portanto, existe apenas uma mesma variável @@ para as classes Person, Student e Graduate e todos os métodos de classe e instância dessas classes se referem à mesma variável.
Existe outra maneira de definir uma variável de classe que é definida em um objeto de classe (lembre-se de que cada classe é na verdade uma instância de algo que na verdade é a classe Class, mas é outra história). Você usa a notação @ em vez de @@, mas não pode acessar essas variáveis nos métodos da instância. Você precisa ter wrappers de método de classe.
Aqui, @people é único por classe, em vez de hierarquia de classes, porque na verdade é uma variável armazenada em cada instância de classe. Esta é a saída:
Uma diferença importante é que, você não pode acessar essas variáveis de classe (ou variáveis de instância de classe, você pode dizer) diretamente dos métodos de instância, porque @people em um método de instância se refere a uma variável de instância dessa instância específica das classes Person, Student ou Graduate .
Portanto, enquanto outras respostas afirmam corretamente que @myvariable (com notação @ única) é sempre uma variável de instância, isso não significa necessariamente que não é uma única variável compartilhada para todas as instâncias dessa classe.
fonte