"George Ogata" <g_ogata@optushome.com.au> schrieb im Newsbeitrag
news:87d61xwbct.fsf@optushome.com.au...
"DaZoner" <nobody@nowhere.com> writes:
> I've defined a class I use that strips methods off of a class
(specified by
> a string representing the class name). I use it maybe 30 times during
my
> application run. However I'm concerned because it does an
> ObjectSpace.each(Class) call to make sure the specified class exists
before
> trying to remove any methods. Will this call get slow as a few arrays
> containing perhaps a million FixNums get defined by the application in
> between calls? The array's data stays around as the calls to my class
are
> made. I've included the source of the class below. If anyone knows an
> efficient way to determine if a class exists given its name in String
form
> I'd sure appreciate seeing it.
>
Something like:
Object.const_defined?(name) && Object.const_get(name).is_a?(Class)
You'd need to tweak it a bit to support nested class names like
C::D::E (in that case you'd need to call C::D.const_defined?('E'),
e.g.).
For example like this:
module Kernel
private
# raises NameError if it's undefined
# raises TypeError if it's not a class
# returns the class instance otherwise
def get_class(class_name)
c = class_name.split(/::|\./).inject(Object) do |cl, name|
cl.const_get name
end
raise TypeError, "Not a class: #{class_name}" unless Class === c
c
end
end
get_class "String"
=> String
get_class "StringX"
NameError: uninitialized constant StringX
from (irb):27:in `const_get'
from (irb):27:in `get_class'
from (irb):26:in `inject'
from (irb):26:in `each'
from (irb):26:in `inject'
from (irb):26:in `get_class'
from (irb):35
get_class "File::Stat"
=> File::Stat
get_class "Enumerable"
TypeError: Not a class: Enumerable
from (irb):29:in `get_class'
from (irb):37
You probable want to include modules as well. Just change to
raise TypeError, "Not a class: #{class_name}" unless Class === c ||
Module === c
get_class "Enumerable"
=> Enumerable
Regards
robert