如何检查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. ....."
答案 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