122

Is there any way to create a variable in a module in Ruby that would behave similar to a class variable? What I mean by this is that it would be able to be accessed without initializing an instance of the module, but it can be changed (unlike constants in modules).

Andrew Grimm
  • 74,534
  • 52
  • 194
  • 322
Mark Szymanski
  • 53,532
  • 23
  • 67
  • 87

4 Answers4

176

Ruby natively supports class variables in modules, so you can use class variables directly, and not some proxy or pseudo-class-variables:

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"
coreyward
  • 73,396
  • 19
  • 130
  • 155
  • 7
    +1 Actually, I have been thinking that the term 'class variable' is misleading. Classes are special cases of modules, and class variables are definable on modules. They should be called module variables. – sawa Apr 17 '11 at 02:54
  • 4
    @sawa: It's somewhat misleading, but it's what Ruby itself uses: `defined?(@@foo) => "class variable"`. – Andrew Grimm Jan 09 '12 at 05:57
  • 1
    Or they could be called static fields. Seems that's what they are. – Peter Ajtai May 11 '12 at 01:11
  • 1
    @coreyward Hey my mistake. Why the need for two '@@' class variables? Isn't it considered a code smell, especially if the class is extended to use class variables? I was testing this and I realized I could get the same result from a single `@` instance variable. Is there a specific reason for using class variables? Thanks for the reply. – MrPizzaFace Jan 25 '14 at 02:14
  • @feed_me_code It's just a part of the language. A class variable is on the actual class, not an instance of the class. In most cases these will behave similarly, but not always. See http://stackoverflow.com/questions/5890118/what-does-variable-mean-in-ruby for a more in-depth explanation. – coreyward Jan 25 '14 at 20:08
  • 2
    why the different calls at the end: `T.get` and `T::get` ? – intrixius Aug 05 '14 at 10:05
  • @intrixius This being so long ago I'm not sure what prompted me to use the `::` notation, perhaps just an effort to show that there are multiple ways of accessing the methods. These two are essentially identical in behavior, but the dot notation is preferred. – coreyward Aug 05 '14 at 17:06
32

If you do not need to call it from within an instance, you can simply use an instance variable within the module body.

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

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

The instance variable @param will then belong to the module SomeModule, which is an instance of the Module class.

sawa
  • 160,959
  • 41
  • 265
  • 366
25

you can set a class instance variable in the module.

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

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

MyModule.var    
=> "this is saved at @var"
Orlando
  • 8,954
  • 2
  • 54
  • 52
8

You can also initialize value within module definition:

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

p MyModule.my_variable
Nakilon
  • 33,683
  • 14
  • 104
  • 137