Forum: Ruby Any way to undef a constant?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2007-02-23 21:33
(Received via mailing list)
Hi,

I'm dynamically compiling ruby code (in a $SAFE=4 environment),
and because I'm not allowed to re-open classes (even tainted ones),
I'm having trouble reloading previously-compiled script code.

As a temporary workaround, each time I compile, I dynamically
create a new module namespace to compile into.

  VER1::DynamicStuff
  VER2::DynamicStuff
  VER3::DynamicStuff
  . . .

Which means all the old versions of the classes created by
previous compiles are hanging around in the system.

What I would like to be able to do (from my $SAFE=0 environment)
is delete (undef) the modules and classes created by the
previous compile.

I can think of a way to sort of accomplish that, by using
reflection, and recursively traversing from the root module,
and telling all contained modules and classes to undef all
their methods, and set all their constants to nil.  However,
I am worried about this solution, because I don't know how
to tell whether the value held by a constant refers to a
dynamically compiled class or not.  (I guess I could just
delete all the 'tainted' stuff.)  ((But even this isn't really
good enough, see below re: SecurityError and re-opening
modules.))

Anyway - am I missing any easy solutions here?  Anyone have
any thoughts as to better approaches?

(What I'd *like* to be able to do, is just say,
"undef MyProg::DynamicStuff", which would undef the
DynamicStuff constant and--presumably--leave the
Module referenced by that constant (and all of its
contents) open for garbage collection.  Note that
just setting the constant to nil isn't good enough,
because I can't later assign a new module to that
constant--because I'll get a SecurityError eventually
when I try to "reopen" that module the next time I
compile in $SAFE=4 .....)


Thanks,

Bill
2c51fec8183a5d21c4e11b430beabb47?d=identicon&s=25 Patrick Hurley (Guest)
on 2007-02-23 21:50
(Received via mailing list)
Try:

ri Module#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.

pth
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2007-02-23 22:22
(Received via mailing list)
From: "Patrick Hurley" <phurley@gmail.com>
> Try:
>
> ri Module#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.


Auuugh!!! How did I miss that !!!!!!!!!!!!!!!!!!!!!!!  :D


Thanks :)


Regards,

Bill
2c51fec8183a5d21c4e11b430beabb47?d=identicon&s=25 Patrick Hurley (Guest)
on 2007-02-25 03:16
(Received via mailing list)
On 2/23/07, Bill Kelly <billk@cts.com> wrote:
> Auuugh!!! How did I miss that !!!!!!!!!!!!!!!!!!!!!!!  :D

You are not the first, I think it is the naming convention. We have
constants, const_get, const_set and remove_const (reversed naming).
Also this is a private method, so you will need to send or instance
eval to get it to work against Object.

> Thanks :)

You are very welcome.
pth
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2007-02-25 21:13
(Received via mailing list)
From: "Patrick Hurley" <phurley@gmail.com>
> On 2/23/07, Bill Kelly <billk@cts.com> wrote:
>> Auuugh!!! How did I miss that !!!!!!!!!!!!!!!!!!!!!!!  :D
>
> You are not the first, I think it is the naming convention. We have
> constants, const_get, const_set and remove_const (reversed naming).

In my case it was "undef" vs. "remove".  I was used to
undef_method.  So I did `ri undef`, and got:

  Module#method_undefined, Module#undef_method,
  Object#singleton_method_undefined, ObjectSpace#undefine_finalizer

So there appeared to be no undef_constant.  However, once you pointed
me to remove_const, I can see we have a much richer set of remove_
methods, only about half of which have undef_ aliases.

  Module#method_removed              Module#method_undefined
  Module#remove_class_variable
  Module#remove_const
  Module#remove_method               Module#undef_method
  Object#remove_instance_variable
  Object#singleton_method_removed    Object#singleton_method_undefined
  ObjectSpace#remove_finalizer       ObjectSpace#undefine_finalizer


From my point of view, it would be nice to add the three
missing _undef aliases.  (Is that worthy of an RCR ?)


Regards,

Bill
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 David A. Black (Guest)
on 2007-02-25 22:52
(Received via mailing list)
Hi --

On 2/25/07, Bill Kelly <billk@cts.com> wrote:
>   Module#method_undefined, Module#undef_method,
>   Object#remove_instance_variable
>   Object#singleton_method_removed    Object#singleton_method_undefined
>   ObjectSpace#remove_finalizer       ObjectSpace#undefine_finalizer
>
>
> From my point of view, it would be nice to add the three
> missing _undef aliases.  (Is that worthy of an RCR ?)

They're not aliases, though. See ri undef_method for illustration of
the difference between undef_method and remove_method.


David
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2007-02-25 23:29
(Received via mailing list)
From: "David A. Black" <dblack@wobblini.net>
> On 2/25/07, Bill Kelly <billk@cts.com> wrote:
>>
>> From my point of view, it would be nice to add the three
>> missing _undef aliases.  (Is that worthy of an RCR ?)
>
> They're not aliases, though. See ri undef_method for illustration of
> the difference between undef_method and remove_method.

Oh, well that's different. Nevermind...  :)


Thanks,

Bill
This topic is locked and can not be replied to.