# Redefining a class

**URL:** <https://www.ruby-forum.com/t/redefining-a-class/74902>\
**Category:** Ruby\
**Created:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902 "2006-11-07T11:01:02Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/1 "2006-11-07T11:01:02Z")

</div>

Hi all

Recently we had a thread where we talked about redefining a class.  
The usefuleness of that did not come into my mind before.

Does somebody know a way to redefine a class (without the "already  
initialized constant " warning)?  
And if there is none, which I suspect, might it not be nice to have one?

Cheers  
Robert

–  
The reasonable man adapts himself to the world; the unreasonable one  
persists in trying to adapt the world to himself. Therefore all progress  
depends on the unreasonable man.

- George Bernard Shaw

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/2 "2006-11-07T11:01:26Z")

</div>

On Sat, 4 Nov 2006, Robert D. wrote:

> Hi all
> 
> Recently we had a thread where we talked about redefining a class.  
> The usefuleness of that did not come into my mind before.
> 
> Does somebody know a way to redefine a class (without the "already  
> initialized constant " warning)?  
> And if there is none, which I suspect, might it not be nice to have one?

c = Class.new{  
def initialize  
@x = ‘foo’  
end  
}  
o = c.new

c = Class.new{  
def initialize  
@x = ‘bar’  
end  
}  
o = c.new

😉

-a

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/3 "2006-11-07T11:01:51Z")

</div>

On 11/4/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > And if there is none, which I suspect, might it not be nice to have one?  
> > def initialize  
> > my religion is very simple. my religion is kindness. – the dalai lama

Actually I am very disappointed that you cannot read my mind Ara 😉 it  
would  
be quite antipols to use  
not constant classnames (wouldn’t be there some warnings too BTW?)

class C…

C=Class.new…

works fine save for the warning I would like to get around

Here go some ideas:

(1) ruby does not insult you for constant redefinition if you assign a  
reference to Class (arrrghh bad dangerous)  
(2) allow an explicit syntax for redefining a class  
(2.a) class A \< B _always_ redefines the class Pro: Some Gurus  
expect  
this behavior anyway 🙂

Cons: Quite implicit  
(2.b) new class A  
Pro:  
Quite POLS and readable

Cons: “new” overloaded maybe use “redefine class A”  
(3) some meta thingies  
(3.a) const\_set does not warn anymore  
(3.b) Matz gives us a const\_undefine for Christmas 😉

Ok what you think?

Robert

–  
The reasonable man adapts himself to the world; the unreasonable one  
persists in trying to adapt the world to himself. Therefore all progress  
depends on the unreasonable man.

- George Bernard Shaw

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/4 "2006-11-07T11:01:56Z")

</div>

On 11/4/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > > 
> > > 
> > > ```
> > > def initialize
> > > 
> > > ```
> > > 
> > > o = c.new  
> > > (Specifically, he said “Policy of least surprise is _my_ least  
> > > surprise”. I think it was at RubyConf 2002.)

And you think we ought let him get away with that 😉

I wouldn’t expect a warning just from assigning a class object to a

> > (1) ruby does not insult you for constant redefinition if you assign a
> 
> > Quite POLS and readable  
> > Cons: “new” overloaded maybe use “redefine class A”  
> > (3) some meta thingies  
> > (3.a) const\_set does not warn anymore  
> > (3.b) Matz gives us a const\_undefine for Christmas 😉
> > 
> > Ok what you think?
> 
> Basically I think that if you find yourself in urgent need of defining  
> a new class using the same constant as one you’ve already defined, you  
> need to review your application design 🙂

Honestly I do not know, probably yes, because it did never even occur to  
me.  
OTH you can already redefine  
classes as Ara showed above, only that one will use a different idiom.  
I can also redefine classes by hiding classes inside Modules e.g. than  
one  
does not know if it is done on purpose or not.  
Imagine the semantic power of  
" redefine class ::String "  
although that kind of code might disgust you (it disgusts me!) it tells  
us  
that the author knows what he does, quite a feature, no?

The warning is probably

> enough of a slap on the wrist to remind you of this.
> 
> I do, however, think that (3.a) might be a good idea. I’m not sure,  
> though.

Thanks that’s more than I expected 😉

David

> –  
> David A. Black | removed\_email\_address@domain.invalid  
> Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]  
> DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]  
> [1] [Ruby for Rails](http://www.manning.com/black) | [3] [http://www.rubypowerandlight.com](http://www.rubypowerandlight.com)  
> [2] [http://dablog.rubypal.com](http://dablog.rubypal.com) | [4] [http://www.rubycentral.org](http://www.rubycentral.org)

Robert

–  
The reasonable man adapts himself to the world; the unreasonable one  
persists in trying to adapt the world to himself. Therefore all progress  
depends on the unreasonable man.

- George Bernard Shaw

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/5 "2006-11-07T11:01:58Z")

</div>

On 11/4/06, Devin M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Devin

How could I have missed that one!!!  
Thx.  
Well it is not perfect but I think it gets the job done  
  
#!/usr/local/bin/ruby

def redefine\_class name, base=Object, &definition  
Object.send :remove\_const, name.to\_s rescue nil  
cls = Object.const\_set name.to\_s, Class.new( base )  
cls.class\_eval &definition if definition  
end

class A  
end  
puts A.object\_id  
redefine\_class A  
puts A.object\_id  
redefine\_class A do  
def greet; puts “hi” end  
end  
A.new.greet

## Useless code, I love it 😉 Robert

The reasonable man adapts himself to the world; the unreasonable one  
persists in trying to adapt the world to himself. Therefore all progress  
depends on the unreasonable man.

- George Bernard Shaw

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/6 "2006-11-07T11:01:56Z")

</div>

## $ ri remove\_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.

For a more thorough answer, read the Rails reloading code.

Devin

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:01am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/7 "2006-11-07T11:01:53Z")

</div>

Hi –

On Sun, 5 Nov 2006, Robert D. wrote:

> > > initialized constant " warning)?  
> > > c = Class.new{  
> > > be quite antipols to use  
> > > not constant classnames (wouldn’t be there some warnings too BTW?)

Don’t forget that several years ago, Matz deprecated POLS 🙂  
(Specifically, he said “Policy of least surprise is _my_ least  
surprise”. I think it was at RubyConf 2002.)

I wouldn’t expect a warning just from assigning a class object to a  
variable.

> (2) allow an explicit syntax for redefining a class  
> (2.a) class A \< B _always_ redefines the class Pro: Some Gurus expect  
> this behavior anyway 🙂

Not a good idea. The inheritance should be a no-op if it already  
exists, and an error if it’s a different class. The expression “A \<  
B” does not in any way imply that A should be undefined. You’d end up  
seeing:

class C \< Object

just to trigger a redefinition. It’s piggy-backing a behavior  
(constant redefinition) on a completely unrelated construct.

> Cons: Quite implicit

And arbitrary.

> (2.b) new class A Pro:  
> Quite POLS and readable  
> Cons: “new” overloaded maybe use “redefine class A”  
> (3) some meta thingies  
> (3.a) const\_set does not warn anymore  
> (3.b) Matz gives us a const\_undefine for Christmas 😉
> 
> Ok what you think?

Basically I think that if you find yourself in urgent need of defining  
a new class using the same constant as one you’ve already defined, you  
need to review your application design 🙂 The warning is probably  
enough of a slap on the wrist to remind you of this.

I do, however, think that (3.a) might be a good idea. I’m not sure,  
though.

David

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:03am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/8 "2006-11-07T11:03:18Z")

</div>

On 11/4/06, David V. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> objects, including classes you intend to redefine.  
> Actually clear like water, I was wrting stupid things, it is only  
> anticonventional .  
> I have problems defending I feature I dislike and yet feel it should be  
> here  
> because…

(On the possibility

> of redefining classes -outside- your code I shan’t speak, because I’d  
> have to get vulgar. Prolific namespace clobbering already gets on my  
> nerves, and I wish there was a way to localise such changes requiring a  
> module causes. /me gets off soapbox.) And I sure as hell would find it  
> surprising if suddenly a hash keyed by what I thought were constant  
> objects started breaking.

… there is some truth(1) in what you are saying.  
No doubt one of the reasions why remove\_const is private.

David V.

> Robert

## (1) although strictly speaking there is no such thing I mean “POV I share to some degrees”

The reasonable man adapts himself to the world; the unreasonable one  
persists in trying to adapt the world to himself. Therefore all progress  
depends on the unreasonable man.

- George Bernard Shaw

---

<div class="post-metadata">

**Author:** ![flatekmonkey](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e8c25b/32.png) [@flatekmonkey](https://www.ruby-forum.com/u/flatekmonkey)\
**Post date:** [November 7, 2006, 11:02am UTC](https://www.ruby-forum.com/t/redefining-a-class/74902/9 "2006-11-07T11:02:16Z")

</div>

Robert D. wrote:

> Actually I am very disappointed that you cannot read my mind Ara 😉 it  
> would  
> be quite antipols to use  
> not constant classnames (wouldn’t be there some warnings too BTW?)

If you redefine the class at times, it’s hardly constant. Personally, I  
think it’s cleaner to use non-constant names for… well… nonconstant  
objects, including classes you intend to redefine. (On the possibility  
of redefining classes -outside- your code I shan’t speak, because I’d  
have to get vulgar. Prolific namespace clobbering already gets on my  
nerves, and I wish there was a way to localise such changes requiring a  
module causes. /me gets off soapbox.) And I sure as hell would find it  
surprising if suddenly a hash keyed by what I thought were constant  
objects started breaking.

David V.
