Redefining a class

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

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

:wink:

-a

On 11/4/06, [email protected] [email protected] 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 :wink: 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 :slight_smile:

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 :wink:

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

On 11/4/06, [email protected] [email protected] 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 :wink:

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 :wink:

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 :slight_smile:

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 :wink:

David


David A. Black | [email protected]
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 | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] 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

On 11/4/06, Devin M. [email protected] 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 :wink:
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

$ 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

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 :slight_smile:
(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 :slight_smile:

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 :wink:

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 :slight_smile: 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

On 11/4/06, David V. [email protected] 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

Robert D. wrote:

Actually I am very disappointed that you cannot read my mind Ara :wink: 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.