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 <ClassName>" 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

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 Sat, 4 Nov 2006, Robert Dober 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 <ClassName>" warning)?
And if there is none, which I suspect, might it not be nice to have one?

--
my religion is very simple. my religion is kindness. -- the dalai lama

$ 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

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

···

On 11/4/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

On Sat, 4 Nov 2006, Robert Dober 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 <ClassName>" 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
--
my religion is very simple. my religion is kindness. -- the dalai lama

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

How could I have missed that one!!!
Thx.
Well it is not perfect but I think it gets the job done
<begin code>
#!/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
<end code>

Useless code, I love it :wink:
Robert

···

On 11/4/06, Devin Mullins <twifkak@comcast.net> wrote:

$ 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

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

Hi --

> 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 <ClassName>" 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:

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?)

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.

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:

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 Sun, 5 Nov 2006, Robert Dober wrote:

On 11/4/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

On Sat, 4 Nov 2006, Robert Dober wrote:

--
                   David A. Black | dblack@wobblini.net
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 Dober 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 Vallner

Hi --

>>
>> > 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 <ClassName>" 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:
>>
> 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?)

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.)

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

variable.

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

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:

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 | dblack@wobblini.net
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

···

On 11/4/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

On Sun, 5 Nov 2006, Robert Dober wrote:
> On 11/4/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
>> On Sat, 4 Nov 2006, Robert Dober wrote:

--
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 Dober 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.

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 Vallner

Robert

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

···

On 11/4/06, David Vallner <david@vallner.net> wrote:
--
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