# Constants in modules

**URL:** <https://www.ruby-forum.com/t/constants-in-modules/138979>\
**Category:** Ruby\
**Created:** [May 29, 2008, 6:00pm UTC](https://www.ruby-forum.com/t/constants-in-modules/138979 "2008-05-29T18:00:59Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![luis21\_futur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/87869e/32.png) [@luis21\_futur](https://www.ruby-forum.com/u/luis21_futur)\
**Post date:** [May 29, 2008, 6:00pm UTC](https://www.ruby-forum.com/t/constants-in-modules/138979/1 "2008-05-29T18:00:59Z")

</div>

Hello,

I need to do something like this (this is a simplified version of some  
other code, of course, but I don’t want to get you lost in details  
unrelated to the problem):

module M

CONST\_A = { ‘k1’ =\> ‘v1’, ‘k2’ =\> ‘v2’ }  
CONST\_B = invert\_hash(CONST\_A)

def method1  
# Do something with CONST\_A  
puts CONST\_A  
end

def method2  
# Do something with CONST\_B  
puts CONST\_B  
end

def invert\_hash(h)  
inverted = {}  
h.each\_pair { |k, v| inverted[v] = k }  
inverted  
end

end

My intention is to be able to calculate CONST\_B by invoking a method in  
the module itself… but I get this error message:

tests.rb:4: undefined method `invert\_hash’ for M:Module (NoMethodError)  
from tests.rb:1

I have tried lots of combinations by prefixing the module name, using  
::, using module\_function, etc., but nothing has worked.

Is there a way to do this? Of course I know there are obvious  
workarounds such as defining the method outside the module, but that  
would be quite ugly… and there should be a way to use code in my own  
module from my own module!!!

Thanks in advance for your help,

```
Luis.
```

---

<div class="post-metadata">

**Author:** ![luis21\_futur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/87869e/32.png) [@luis21\_futur](https://www.ruby-forum.com/u/luis21_futur)\
**Post date:** [May 29, 2008, 6:07pm UTC](https://www.ruby-forum.com/t/constants-in-modules/138979/2 "2008-05-29T18:07:33Z")

</div>

Two things - firstly, Ruby is interpreted, so invert\_hash needs to be  
declared _before_ you use it. Then, your methods need to be module  
methods - just put a “self.” before each one, and it should work.

---

<div class="post-metadata">

**Author:** ![luis21\_futur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/87869e/32.png) [@luis21\_futur](https://www.ruby-forum.com/u/luis21_futur)\
**Post date:** [May 29, 2008, 7:46pm UTC](https://www.ruby-forum.com/t/constants-in-modules/138979/3 "2008-05-29T19:46:42Z")

</div>

Bryan JJ Buckley wrote:

> Two things - firstly, Ruby is interpreted, so invert\_hash needs to be  
> declared _before_ you use it. Then, your methods need to be module  
> methods - just put a “self.” before each one, and it should work.

Yes, it works!!

I already tried defining the method as a module method by prepending the  
module name to the method name, which AFAIK it is totally equivalent to  
prepending self.

…But I did not realize that the constant code is executed when reading  
the module, so I had to define the method before.

Thank you!

```
Luis.
```

---

<div class="post-metadata">

**Author:** ![luis21\_futur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/87869e/32.png) [@luis21\_futur](https://www.ruby-forum.com/u/luis21_futur)\
**Post date:** [May 29, 2008, 11:20pm UTC](https://www.ruby-forum.com/t/constants-in-modules/138979/4 "2008-05-29T23:20:17Z")

</div>

Luis Crespo wrote:

> …But I did not realize that the constant code is executed when reading  
> the module, so I had to define the method before.

Yes, this is a common gotcha.

Personally I like to have the main program at the top of my code, but  
Ruby wants me to put it at the bottom, so it’s seen all the function  
definitions before I try to call them. You can get around it like this:

def main

# …

end

def function1

# …

end

def function2

# …

end

main

Defining a “main” function comes naturally to C programmers, but in Ruby  
you actually have to call it at the bottom. 😉
