Crie variáveis ​​de módulo em Ruby


111

Existe alguma maneira de criar uma variável em um módulo em Ruby que se comportaria de forma semelhante a uma variável de classe? O que quero dizer com isso é que ele poderia ser acessado sem inicializar uma instância do módulo, mas pode ser alterado (ao contrário das constantes nos módulos).

Respostas:


158

Ruby oferece suporte nativo a variáveis ​​de classe em módulos, então você pode usar variáveis ​​de classe diretamente, e não algum proxy ou variáveis ​​de pseudo-classe:

module Site
  @@name = "StackOverflow"

  def self.setName(value)
    @@name = value
  end

  def self.name
    @@name
  end
end

Site.name            # => "StackOverflow"
Site.setName("Test")
Site.name            # => "Test"

5
1 Na verdade, tenho pensado que o termo 'variável de classe' é enganoso. As classes são casos especiais de módulos e as variáveis ​​de classe podem ser definidas nos módulos. Eles devem ser chamados de variáveis ​​de módulo.
sawa

3
@sawa: É um pouco enganador, mas é o que o próprio Ruby usa: defined?(@@foo) => "class variable".
Andrew Grimm

1
Ou eles podem ser chamados de campos estáticos. Parece que eles são.
Peter Ajtai

@coreyward Ei, meu erro. Por que a necessidade de duas variáveis ​​de classe '@@'? Não é considerado um cheiro de código, especialmente se a classe for estendida para usar variáveis ​​de classe? Eu estava testando isso e percebi que poderia obter o mesmo resultado de uma única @variável de instância. Existe uma razão específica para usar variáveis ​​de classe? Obrigado pela resposta.
fabbb

2
por que as diferentes chamadas no final: T.gete T::get?
intrixius

31

Se você não precisa chamá-lo de dentro de uma instância, você pode simplesmente usar uma variável de instância dentro do corpo do módulo.

module SomeModule
  module_function
  def param; @param end
  def param= v; @param = v end
end

SomeModule.param
# => nil
SomeModule.param = 1
SomeModule.param
# => 1

A variável de instância @paramentão pertencerá ao módulo SomeModule, que é uma instância da Moduleclasse.


23

você pode definir uma variável de instância de classe no módulo.

module MyModule
   class << self; attr_accessor :var; end
end

MyModule.var = 'this is saved at @var'

MyModule.var    
=> "this is saved at @var"

+1, mas vou apenas enfatizar que as variáveis ​​de instância de classe são diferentes das variáveis ​​de classe.
Andrew Grimm

4
sim, totalmente .. e btw .. eu não recomendo usar variáveis ​​de classe .. algumas coisas inesperadas acontecem quando você as usa .. verifique este artigo para ver alguns exemplos oreillynet.com/ruby/blog/2007/01/…
Orlando

8

Você também pode inicializar o valor na definição do módulo:

module MyModule
  class << self
    attr_accessor :my_variable
  end
  self.my_variable = 2 + 2
end

p MyModule.my_variable
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.