Any way to undef a constant?


#1

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


#2

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


#3

From: “Patrick H.” removed_email_address@domain.invalid

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

Thanks :slight_smile:

Regards,

Bill


#4

On 2/23/07, Bill K. removed_email_address@domain.invalid wrote:

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

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

You are very welcome.
pth


#5

Hi –

On 2/25/07, Bill K. removed_email_address@domain.invalid 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


#6

From: “Patrick H.” removed_email_address@domain.invalid

On 2/23/07, Bill K. removed_email_address@domain.invalid wrote:

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

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


#7

From: “David A. Black” removed_email_address@domain.invalid

On 2/25/07, Bill K. removed_email_address@domain.invalid 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… :slight_smile:

Thanks,

Bill