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).
Asked
Active
Viewed 1.1e+01k times
4 Answers
184
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
- 77,547
- 20
- 137
- 166
-
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
-
1Or 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
-
2why 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
-
The only thing I probably remove is the Setter, that's breaking the Open/Close Principle from SOLID. If you need to mutate the value highly suggest to use a Instance Variable. – Julian Aug 16 '22 at 06:11
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
- 165,429
- 45
- 277
- 381
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
- 9,374
- 3
- 56
- 53
-
2+1, but I'll just emphasize that class instance variables are different to class variables. – Andrew Grimm Jan 09 '12 at 05:58
-
Btw also the encapsulation of the ATTR should not be 'read and write' should be just 'read': class << self; attr_reader :var; end And even that is not the proper solution for this case – Julian Aug 16 '22 at 06:07
-
@Julian not sure what you mean, this is just an example and you can use `attr_accessor` or `attr_reader` depending on your use case – Orlando Aug 16 '22 at 19:26
9
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
- 34,866
- 14
- 107
- 142
-
I did not recommend to mutate a class variable, that's breaking the encapsulation rules. Also not following the Open/Close Principle from SOLID – Julian Aug 16 '22 at 06:09
-
@julian This creates a class instance variable (since Modules are classes), right? Not sure how this breaks encapsulation... – TenJack Apr 24 '23 at 21:36
-
Metaprogramming is an antipattern, that brakes the encapsulation principle. – Julian May 03 '23 at 21:47