# Removing a constant definition from an environment

**URL:** <https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890>\
**Category:** Ruby\
**Created:** [November 14, 2005, 10:29pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890 "2005-11-14T22:29:25Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 14, 2005, 10:29pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/1 "2005-11-14T22:29:25Z")

</div>

Hi,

I am running unit tests that test the assignment of a constant value  
in a “config” file that is actually ruby code, e.g.

VARIABLE=“somevalue”

On subsequent test methods in my unit test, I get a complaint that it  
is already assigned.

setup  
load const  
end

def test\_1  
do something  
end

def test\_2  
do something else  
end

test 2 gets a warning that const has already been defined.

I expected the unit test to clean the environment, in lieu of that,  
how can I undefined const?

Thanks,  
Bob

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 14, 2005, 10:47pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/2 "2005-11-14T22:47:27Z")

</div>

On 11/14/05, Robert E. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I expected the unit test to clean the environment, in lieu of that,  
> how can I undefined const?

## ---------------------------------------------------- Module#remove\_const remove\_const(sym) =\> obj

```
 Removes the definition of the given constant, returning that
 constant's value. Predefined classes and singleton objects (such as
 _true_) cannot be removed.

```

You pass it a symbol: remove\_const(:VARIABLE)

Ryan

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 14, 2005, 10:59pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/3 "2005-11-14T22:59:29Z")

</div>

Hi Ryan,

Thanks for your help.

I tried that, and it didn’t work. Here is my irb transcript trying  
that. Is there another way to remove a constant? I thought I had seen  
one in the Pickaxe book, but maybe I was thinking of the module method.

irb  
irb(main):001:0\> FOO = “my symbol value”  
=\> “my symbol value”  
irb(main):002:0\> remove\_const(FOO)  
NoMethodError: undefined method `remove_const' for main:Object from (irb):2 irb(main):003:0> remove_const(:FOO) NoMethodError: undefined method`remove\_const’ for main:Object  
from (irb):3  
irb(main):004:0\> ??

Any other ideas?

Thanks,  
Bob E.

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 14, 2005, 11:17pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/4 "2005-11-14T23:17:33Z")

</div>

On Tue, Nov 15, 2005 at 06:56:59AM +0900, Robert E. wrote:

> =\> “my symbol value”  
> irb(main):002:0\> remove\_const(FOO)  
> NoMethodError: undefined method `remove\_const’ for main:Object  
> from (irb):2  
> irb(main):003:0\> remove\_const(:FOO)

Object.remove\_const(:FOO)

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 14, 2005, 11:20pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/5 "2005-11-14T23:20:33Z")

</div>

On Tue, Nov 15, 2005 at 07:16:06AM +0900, Mauricio Fernández wrote:

> > irb(main):001:0\> FOO = “my symbol value”  
> > =\> “my symbol value”  
> > irb(main):002:0\> remove\_const(FOO)  
> > NoMethodError: undefined method `remove\_const’ for main:Object  
> > from (irb):2  
> > irb(main):003:0\> remove\_const(:FOO)

Sorry, I meant  
Object.send(:remove\_const, :FOO)

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 14, 2005, 11:23pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/6 "2005-11-14T23:23:34Z")

</div>

Ryan,

This is a tricky problem. First, you can’t call remove\_const directly  
as it’s a private method on the Module class. In the simple case, that  
means you have to call it from within the class or module from which  
you want to remove a constant. Further, that call must be made from  
within a _class_ (as opposed to instance) method. Here is a simple  
program which shows a class which can define and undefine a constant.  
If you run it with ruby you should see the output in the comments

class Foo  
def self.define\_constant  
class\_eval “CONST\_VAL = 1”  
end

def self.undef\_constant  
remove\_const :CONST\_VAL  
end  
end

puts “CONST\_VAL defined?: #{Foo.const\_defined?(:CONST\_VAL)}”  
Foo.define\_constant  
puts “CONST\_VAL defined now?: #{Foo.const\_defined?(:CONST\_VAL)}”  
Foo.undef\_constant  
puts “CONST\_VAL still defined?: #{Foo.const\_defined?(:CONST\_VAL)}”

# output:

#CONST\_VAL defined?: false  
#CONST\_VAL defined now?: true  
#CONST\_VAL still defined?: false

There are trickier ways to do this with the “send” method but this be  
enough should get you started.

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 15, 2005, 12:08am UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/7 "2005-11-15T00:08:42Z")

</div>

Thanks for all responses. I think I can work something out based on  
these. I’ll post my answer.

Bob

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 14, 2005, 11:26pm UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/8 "2005-11-14T23:26:34Z")

</div>

On 11/14/05, Robert E. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> =\> “my symbol value”  
> irb(main):002:0\> remove\_const(FOO)  
> NoMethodError: undefined method `remove_const' for main:Object from (irb):2 irb(main):003:0> remove_const(:FOO) NoMethodError: undefined method `remove\_const’ for main:Object  
> from (irb):3  
> irb(main):004:0\> ??
> 
> Any other ideas?

This is one of those odd methods that is hard to call. It is actually  
a private method in Module, which means you must call it on a module  
or class, and because it is private you must use send if you want to  
call it from outside the class or module:

irb(main):001:0\> FOO = “something”  
=\> “something”  
irb(main):002:0\> Object.const\_defined?(:FOO)  
=\> true  
irb(main):003:0\> Object.send(:remove\_const, :FOO)  
=\> “something”  
irb(main):004:0\> FOO  
NameError: uninitialized constant FOO  
from (irb):4

But it is better to do something like this:

irb(main):005:0\> class Test  
irb(main):006:1\> FOO = “something”  
irb(main):007:1\> end  
=\> “something”  
irb(main):008:0\> class Test  
irb(main):009:1\> FOO = “something else”  
irb(main):010:1\> end  
(irb):9: warning: already initialized constant FOO  
=\> “something else”  
irb(main):011:0\> class Test  
irb(main):012:1\> remove\_const(:FOO)  
irb(main):013:1\> FOO = “yet something else”  
irb(main):014:1\> end  
=\> “yet something else”

In other words you should call remove\_const from inside the class  
definition before re-creating it.

Ryan

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 15, 2005, 2:48am UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/9 "2005-11-15T02:48:04Z")

</div>

On 11/14/05, Mauricio FernÃ¡ndez [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > irb  
> > > irb(main):001:0\> FOO = “my symbol value”  
> > > =\> “my symbol value”  
> > > irb(main):002:0\> remove\_const(FOO)  
> > > NoMethodError: undefined method `remove\_const’ for main:Object  
> > > from (irb):2  
> > > irb(main):003:0\> remove\_const(:FOO)
> 
> Sorry, I meant  
> Object.send(:remove\_const, :FOO)

I may be wrong, but I think using #send to bypass private method  
encapsulation is not future-proof. Instead, you might use

Object.instance\_eval{ remove\_const :FOO }

This is almost guaranteed to work in the future.

cheers,  
Mark

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 15, 2005, 6:18am UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/10 "2005-11-15T06:18:30Z")

</div>

Hey Everybody,

Thanks for your help. I went for Mark’s approach of using  
Object.instance\_eval(:remove\_const, :FOO).

I want to make sure I understand what is going on, so let me know if  
I get the reason this works wrong.

This works because: Object includes Kernel which is a Module, so it  
gets all the methods on Module, which includes remove\_const. Is that  
correct?

Thanks,  
Bob E.

---

<div class="post-metadata">

**Author:** ![robert.evans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/47e85d/32.png) [@robert.evans](https://www.ruby-forum.com/u/robert.evans)\
**Post date:** [November 15, 2005, 10:22am UTC](https://www.ruby-forum.com/t/removing-a-constant-definition-from-an-environment/47890/11 "2005-11-15T10:22:30Z")

</div>

On Tue, Nov 15, 2005 at 10:44:48AM +0900, Mark H. wrote:

> On 11/14/05, Mauricio Fernández [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Sorry, I meant  
> > Object.send(:remove\_const, :FOO)
> 
> I may be wrong, but I think using #send to bypass private method  
> encapsulation is not future-proof.

Right, [eigenclass.org](http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l11)
