Check whether a class is defined, listing all classes

Given a string of fully-qualified class name, how do I easily check
whether the class is defined or not? I hope it’s not as ‘hard’ as I think:

def class_defined?(classname)
m = Class
classname.split("::").each { |c|
m.constants.include?© or return false
m = m.const_get c
}
return true
end

p class_defined?(“Test::Unit::TestCase”) # false
require 'test/unit/testcase’
p class_defined?(“Test::Unit::TestCase”) # true

Is there an easier way?

A bonus question, how do I list all the defined classes in their fully
qualified name? Example output:

Object
String
FalseClass
Struct
Struct::Tms
File
File::Stat

(My own code is very ugly, I’m embarrassed to show it :slight_smile:

···


dave

“David Garamond” lists@zara.6.isreserved.com schrieb im Newsbeitrag
news:401CC702.9030908@zara.6.isreserved.com

Given a string of fully-qualified class name, how do I easily check
whether the class is defined or not? I hope it’s not as ‘hard’ as I think:

def class_defined?(classname)
m = Class
classname.split(“::”).each { |c|
m.constants.include?(c) or return false
m = m.const_get c
}
return true
end

p class_defined?(“Test::Unit::TestCase”) # false
require ‘test/unit/testcase’
p class_defined?(“Test::Unit::TestCase”) # true

Is there an easier way?

irb(main):009:0> defined? Test::Unit::TestCase
=> nil
irb(main):010:0> require ‘test/unit/testcase’
=> true
irb(main):011:0> defined? Test::Unit::TestCase
=> “constant”
irb(main):012:0>

A bonus question, how do I list all the defined classes in their fully
qualified name? Example output:

Object
String
FalseClass
Struct
Struct::Tms
File
File::Stat

(My own code is very ugly, I’m embarrassed to show it :slight_smile:

ObjectSpace.each_object( Class ){|cl| p cl}
ObjectSpace.each_object( Class ){|cl| p cl.name}

Regards

robert

Robert Klemme wrote:

p class_defined?(“Test::Unit::TestCase”) # false
require ‘test/unit/testcase’
p class_defined?(“Test::Unit::TestCase”) # true

Is there an easier way?

irb(main):009:0> defined? Test::Unit::TestCase
=> nil
irb(main):010:0> require ‘test/unit/testcase’
=> true
irb(main):011:0> defined? Test::Unit::TestCase
=> “constant”

But what if the class name to be checked is a string?
(“Test::Unit::TestCase”)? Btw, is “defined?” a method (of what class?)?
A statement?

A bonus question, how do I list all the defined classes in their fully
qualified name? Example output:

ObjectSpace.each_object( Class ){|cl| p cl}
ObjectSpace.each_object( Class ){|cl| p cl.name}

Ah, Class#name… Thanks, I’m so glad it’s straightforward & easy.

···


dave

“David Garamond” lists@zara.6.isreserved.com schrieb im Newsbeitrag
news:401CEDC9.8000804@zara.6.isreserved.com

Robert Klemme wrote:

p class_defined?(“Test::Unit::TestCase”) # false
require ‘test/unit/testcase’
p class_defined?(“Test::Unit::TestCase”) # true

Is there an easier way?

irb(main):009:0> defined? Test::Unit::TestCase
=> nil
irb(main):010:0> require ‘test/unit/testcase’
=> true
irb(main):011:0> defined? Test::Unit::TestCase
=> “constant”

But what if the class name to be checked is a string?
(“Test::Unit::TestCase”)?

irb(main):005:0> eval "defined? " + “Test::Unit::TestCase”
=> nil
irb(main):006:0> require ‘test/unit/testcase’
=> true
irb(main):007:0> eval "defined? " + “Test::Unit::TestCase”
=> “constant”

Btw, is “defined?” a method (of what class?)?
A statement?

It’s an operator:
http://www.rubycentral.com/book/tut_expressions.html

A bonus question, how do I list all the defined classes in their fully
qualified name? Example output:

ObjectSpace.each_object( Class ){|cl| p cl}
ObjectSpace.each_object( Class ){|cl| p cl.name}

Ah, Class#name… Thanks, I’m so glad it’s straightforward & easy.

:slight_smile:

robert

Robert Klemme wrote:

But what if the class name to be checked is a string?
(“Test::Unit::TestCase”)?

irb(main):005:0> eval "defined? " + “Test::Unit::TestCase”
=> nil
irb(main):006:0> require ‘test/unit/testcase’
=> true
irb(main):007:0> eval "defined? " + “Test::Unit::TestCase”
=> “constant”

Hm, I should’ve added that I didn’t want to involve ‘eval’. But then why
not, I’ll just need to check the input using a simple regexp. After all,
almost everything in Ruby (require, load, irb, class_eval) is using eval
anyway…

Thanks again.

···


dave

Hm, I should've added that I didn't want to involve 'eval'. But then why
not, I'll just need to check the input using a simple regexp.

well, if you think that a simple regexp can do anything against the evil
eval, then you have perhaps a P background :slight_smile:

Guy Decoux

Take a look at StandardClassExtensions on the Wiki. There’s something
in there just for you :slight_smile:

Cheers,
Gavin

···

On Monday, February 2, 2004, 12:52:30 AM, David wrote:

Robert Klemme wrote:

But what if the class name to be checked is a string?
(“Test::Unit::TestCase”)?

irb(main):005:0> eval "defined? " + “Test::Unit::TestCase”
=> nil
irb(main):006:0> require ‘test/unit/testcase’
=> true
irb(main):007:0> eval "defined? " + “Test::Unit::TestCase”
=> “constant”

Hm, I should’ve added that I didn’t want to involve ‘eval’. But then why
not, I’ll just need to check the input using a simple regexp. After all,
almost everything in Ruby (require, load, irb, class_eval) is using eval
anyway…

ts wrote:

“D” == David Garamond lists@zara.6.isreserved.com writes:
Hm, I should’ve added that I didn’t want to involve ‘eval’. But then why
not, I’ll just need to check the input using a simple regexp.

well, if you think that a simple regexp can do anything against the evil
eval, then you have perhaps a P background :slight_smile:

Don’t you also have a P background? :slight_smile: (Or Matz? Or many others?)

guy decoux perl - Google Search

Anyway, I didn’t say regexp can make eval safe generally, but only for
my case:

def class_defined?(classname)
classname.kind_of? String or
raise ArgumentError, “please give me string”
classname =~ /\A[A-Z][A-Za-z0-9_](::[A-Z][A-Za-z0-9_])*\z/ or
raise ArgumentError, “invalid class name”
eval("defined? " + classname) != nil
end

Please do tell me if the above is unsafe…

···


dave

“David Garamond” lists@zara.6.isreserved.com schrieb im Newsbeitrag
news:401D1FF4.6000900@zara.6.isreserved.com

ts wrote:

“D” == David Garamond lists@zara.6.isreserved.com writes:
Hm, I should’ve added that I didn’t want to involve ‘eval’. But then
why
not, I’ll just need to check the input using a simple regexp.

well, if you think that a simple regexp can do anything against the
evil
eval, then you have perhaps a P background :slight_smile:

Don’t you also have a P background? :slight_smile: (Or Matz? Or many others?)

guy decoux perl - Google Search

Anyway, I didn’t say regexp can make eval safe generally, but only for
my case:

def class_defined?(classname)
classname.kind_of? String or
raise ArgumentError, “please give me string”
classname =~ /\A[A-Z][A-Za-z0-9_](::[A-Z][A-Za-z0-9_])*\z/ or
raise ArgumentError, “invalid class name”
eval("defined? " + classname) != nil

You don’t need to compare with nil, that’s converting something to a boolean
that is essentially a boolean already - unless, of course, if you want to
hide the outcome of “defined?”…

To make the methods semantic match the name you should do

eval("defined? " + classname) && Class === eval(classname)

Because otherwise you will get true for all sorts of constants. (Try with
“IO::CREAT”)

end

Please do tell me if the above is unsafe…

Looks safe enough.

robert