如何检查Ruby中是否已存在类

时间:2009-07-27 08:38:32

标签: ruby class

如何检查Ruby中是否已存在类?

我的代码是:

puts "enter the name of the Class to see if it exists"   
nameofclass=gets.chomp  
eval (" #{nameofclass}......  Not sure what to write here")

我在考虑使用:

eval "#{nameofclass}ancestors.     ....."

12 个答案:

答案 0 :(得分:72)

您可以使用Module.const_get来获取字符串引用的常量。它将返回常量(通常类由常量引用)。然后,您可以检查常量是否为类。

我会沿着这些方向做点什么:

def class_exists?(class_name)
  klass = Module.const_get(class_name)
  return klass.is_a?(Class)
rescue NameError
  return false
end

另外,如果可能,我会在接受用户输入时始终避免使用eval;我怀疑这将用于任何严肃的应用程序,但值得了解安全风险。

答案 1 :(得分:45)

也许你可以用定义来做到这一点?

例如:

if defined?(MyClassName) == 'constant' && MyClassName.class == Class  
   puts "its a class" 
end

注意:需要进行班级检查,例如:

Hello = 1 
puts defined?(Hello) == 'constant' # returns true

回答原来的问题:

puts "enter the name of the Class to see if it exists"
nameofclass=gets.chomp
eval("defined?(#{nameofclass}) == 'constant' and #{nameofclass}.class == Class")

答案 2 :(得分:25)

如果您通过调用Module.const_get查看某个范围内的常量,则可以避免从Module#const_defined?("SomeClass")中解救NameError。

调用它的常见范围是Object,例如:Object.const_defined?("User")

请参阅:“Module”。

答案 3 :(得分:11)

defined?(DatabaseCleaner) # => nil
require 'database_cleaner'
defined?(DatabaseCleaner) # => constant

答案 4 :(得分:8)

类名是常量。您可以使用defined?方法查看是否已定义常量。

defined?(String)    # => "constant"
defined?(Undefined) # => nil

如果您有兴趣,可以详细了解defined?如何运作。

答案 5 :(得分:6)

这是一个更简洁的版本:

def class_exists?(class_name)
  eval("defined?(#{class_name}) && #{class_name}.is_a?(Class)") == true
end

class_name = "Blorp"
class_exists?(class_name)
=> false

class_name = "String"
class_exists?(class_name)
=> true

答案 6 :(得分:6)

Kernel.const_defined?("Fixnum") # => true

答案 7 :(得分:4)

我有时会采取一些措施来解决这个问题。您可以将以下方法添加到String类中,如下所示:

class String
    def to_class
        my_const = Kernel.const_get(self)
        my_const.is_a?(Class) ? my_const : nil
    rescue NameError 
        nil
    end

    def is_a_defined_class?
        true if self.to_class
    rescue NameError
        false
    end
end

然后:

'String'.to_class
=> String
'unicorn'.to_class
=> nil
'puppy'.is_a_defined_class?
=> false
'Fixnum'.is_a_defined_class?
=> true

答案 8 :(得分:2)

在一行中,我会写:

!!Module.const_get(nameofclass) rescue false

仅当给定的true属于已定义的类时才会返回nameofclass

答案 9 :(得分:1)

我用它来查看是否在运行时加载了一个类:

def class_exists?(class_name)
  ObjectSpace.each_object(Class) {|c| return true if c.to_s == class_name }
  false
end

答案 10 :(得分:0)

我假设如果未加载课程,你会采取一些行动。

如果您要求提供文件,为什么不检查require的输出?

require 'already/loaded'  
=> false

答案 11 :(得分:0)

如果您想要打包,finishing_moves gem会添加class_exists?方法。

class_exists? :Symbol
# => true
class_exists? :Rails
# => true in a Rails app
class_exists? :NonexistentClass
# => false