# Is there a way to make class and object constants in Ruby?

**URL:** <https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969>\
**Category:** Ruby\
**Created:** [April 15, 2010, 3:01am UTC](https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969 "2010-04-15T03:01:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Xeno\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/958977/32.png) [@Xeno\_C](https://www.ruby-forum.com/u/Xeno_C)\
**Post date:** [April 15, 2010, 3:01am UTC](https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969/1 "2010-04-15T03:01:16Z")

</div>

I am reading up in other areas, and it occurs to me much of the items I  
have as  
class and object variables really should be constants, but ideally still  
in the  
class or object context. Is there a way to do this?

xc

---

<div class="post-metadata">

**Author:** ![Xeno\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/958977/32.png) [@Xeno\_C](https://www.ruby-forum.com/u/Xeno_C)\
**Post date:** [April 15, 2010, 3:36am UTC](https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969/2 "2010-04-15T03:36:24Z")

</div>

On Wed, Apr 14, 2010 at 8:00 PM, Xeno C.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> I am reading up in other areas, and it occurs to me much of the items I  
> have as class and object variables really should be constants, but ideally  
> still in the class or object context. Is there a way to do this?
> 
> ## xc
> 
> “It’s the preponderance, stupid!” - Professor Stephen Schneider, IPCC  
> member

Variables that begin with capital letters are constants

initial\_constants = Module.constants  
class MyClass  
MY\_FAVOURITE\_NUMBER = 12  
MyFavouriteNumber = 12  
end  
Module.constants - initial\_constants # =\> [:MyClass]  
MyClass.constants # =\> [:MY\_FAVOURITE\_NUMBER, :MyFavouriteNumber]

So you can see that classes are already constants, and an example of how  
to  
create constants within a class.

In Ruby, this really means that the reference may not be changed (or at  
least you will be warned if you try to do so), not that the object being  
referenced may not be mutated.

class MyClass  
MyFavouriteNumber = 12  
MyFavouriteNumber = 13 # !\> already initialized constant  
MyFavouriteNumber  
MyFavouriteNumber # =\> 13  
end

If you change your constant, you will know, it will warn you (ie, it  
won’t  
happen by accident). If your code breaks because of this… well…  
you’ll  
have a pretty good idea where to look. While Ruby is dynamic enough to  
make  
such a change, it is not something you should do. If you need to change  
your  
constants, then they shouldn’t be constants.

If you really need your data to not change, to the point where you don’t  
even want to allow yourself the opportunity to do so, you can freeze it,  
and  
it will throw an exception

class MyClass  
MyFavouriteWord = “ambivalent”  
MyFavouriteWord \<\< ‘l’  
MyFavouriteWord # =\> “ambivalentl”  
MyFavouriteWord.freeze  
MyFavouriteWord \<\< ‘y’  
MyFavouriteWord # =\>  
end

# ~\> -:6:in `class:MyClass’: can’t modify frozen string (RuntimeError)

# ~\> from -:1:in `’

But as far as I am aware, there is no way to recursively free any  
references  
it has (probably a good thing, you could recursively freeze your entire  
program)

class MyClass

SomeArray = [‘abc’ , ‘def’].freeze  
SomeArray # =\> [“abc”, “def”]

begin  
SomeArray \<\< ‘ghi’  
rescue =\> e  
e # =\> #\<RuntimeError: can’t modify frozen array\>  
end

SomeArray.last # =\> “def”  
SomeArray.last \<\< ‘ghi’  
SomeArray.last # =\> “defghi”

end

Generally, constants are used for data that should be hard coded in, you  
use  
a constant so that you can easily change it later, like using a macro in  
C.  
You can then drop it into your code, and it is replaced with the actual  
value (you can redefine macros too). And they are also used for keeping  
important references, like the constant STDIN. We can change the global  
we  
use as stdin, but we don’t want to lose track the actual stdin, so we  
keep  
it in the constant.

STDIN # =\> #\<IO:\>  
$stdin # =\> #\<IO:\>

$stdin = DATA # =\> #\<File:untitled\>  
gets # =\> “this is the data\n”

$stdin = STDIN # =\> #\<IO:\>

**END**  
this is the data

---

<div class="post-metadata">

**Author:** ![Xeno\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/958977/32.png) [@Xeno\_C](https://www.ruby-forum.com/u/Xeno_C)\
**Post date:** [April 15, 2010, 3:42am UTC](https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969/3 "2010-04-15T03:42:51Z")

</div>

Am Wed, 14 Apr 2010 20:00:54 -0500 schrieb Xeno C.:

> I am reading up in other areas, and it occurs to me much of the items I  
> have as class and object variables really should be constants, but  
> ideally still in the class or object context. Is there a way to do  
> this?
> 
> xc

In class context you could do:

class MyClass

MYCONSTANT=6

def initialize  
puts MYCONSTANT  
end

end

But I wonder, whether it makes sense at all to have constants at object  
level. This sounds weird to me.

Thomas

---

<div class="post-metadata">

**Author:** ![Xeno\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/958977/32.png) [@Xeno\_C](https://www.ruby-forum.com/u/Xeno_C)\
**Post date:** [April 20, 2010, 1:38am UTC](https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969/4 "2010-04-20T01:38:47Z")

</div>

Thank you Josh and Thomas. The source of this question is my study of  
Erlang,  
where all ‘Variables’ do not vary after the initial assignment. I  
realized when  
reading up on the language that there are many areas in my classes where  
the  
thing I use, especially with Object Variables, are effectively  
constants, so I  
would do best to have them as actual constants. It turns out there is a  
lot of  
value in knowing that something cannot change, even if it can change but  
will  
have at least an obvious error. I don’t expect to Erlangize my  
programs, but I  
have already identified things I can do to make my stuff safer and  
clearer just  
by making class and object variables into constants. Too bad there is  
not a  
special prefix for these as there is for the variables. That would be  
nice for  
referencing things. Still, no big deal.

xc

---

<div class="post-metadata">

**Author:** ![Xeno\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/958977/32.png) [@Xeno\_C](https://www.ruby-forum.com/u/Xeno_C)\
**Post date:** [April 20, 2010, 4:23pm UTC](https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969/5 "2010-04-20T16:23:15Z")

</div>

To make objects immutable you can ‘freeze’ them. After being frozen  
any attempt  
to change will result in an error:

> > x = ‘test’  
> > =\>  
> > “test”
> 
> > x.freeze  
> > =\>  
> > “test”
> 
> > x[0] = ‘w’  
> > RuntimeError: can’t modify frozen string

---

<div class="post-metadata">

**Author:** ![Xeno\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/958977/32.png) [@Xeno\_C](https://www.ruby-forum.com/u/Xeno_C)\
**Post date:** [April 15, 2010, 5:27am UTC](https://www.ruby-forum.com/t/is-there-a-way-to-make-class-and-object-constants-in-ruby/186969/6 "2010-04-15T05:27:36Z")

</div>

On Wed, Apr 14, 2010 at 8:40 PM, Thomas Volkmar W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> But I wonder, whether it makes sense at all to have constants at object  
> level. This sounds weird to me.
> 
> Thomas

I do for things that don’t (or shouldn’t) change. For example, I’m  
working  
on a Rails project where the admin can assign a level of trust to a user  
such that they can post images directly to the main page from Twitter.  
The  
database doesn’t inherently support enumerated types, so the attribute  
is an  
integer, then I have class level constants that map those values to  
their  
meanings, and a set of methods that allow you to get booleans back when  
asking if that user is able to do that authorized thing, and they are  
embedded into named scopes so that I can pull all users who have this  
authorization level, or that authorization level, and so forth. So I  
just  
store a single integer in the database, but my application interprets it  
the  
same across every instance.
