如何检查一个类是否已经存在于Ruby中
如何检查一个类是否已经存在于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. ....."
您可以使用Module.const_get
来获取string引用的常量。 它将返回常量(通常类是由常量引用的)。 然后可以检查常量是否是一个类。
我会按照这些方式做一些事情:
def class_exists?(class_name) klass = Module.const_get(class_name) return klass.is_a?(Class) rescue NameError return false end
另外,如果可能的话,我总是避免在接受用户input时使用eval
; 我怀疑这将被用于任何严重的应用程序,但值得注意的安全风险。
也许你可以用它来做到这一点?
例如:
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")
如果通过调用Module#const_defined?("SomeClass")
来查看某个范围内的常量,则可以避免必须从Module.const_get
拯救NameError。
调用这个的通用范围是Object,例如: Object.const_defined?("User")
。
请参阅:“ 模块 ”。
defined?(DatabaseCleaner) # => nil require 'database_cleaner' defined?(DatabaseCleaner) # => constant
类名称是常量。 你可以使用defined?
方法来查看是否已经定义了一个常量。
defined?(String) # => "constant" defined?(Undefined) # => nil
你可以阅读更多关于如何defined?
如果你感兴趣的话
这是一个更简洁的版本:
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
Kernel.const_defined?("Fixnum") # => true
这是我有时做的解决这个问题的方法。 您可以将以下方法添加到String类中,如下所示:
class String def to_class Kernel.const_get self 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
我用它来查看一个类是否在运行时被加载:
def class_exists?(class_name) ObjectSpace.each_object(Class) {|c| return true if c.to_s == class_name } false end
在一行中,我会写:
!!Module.const_get(nameofclass) rescue false
只有给定的nameofclass
属于一个定义的类,才会返回true
。
我假设你会采取一些行动,如果类没有加载。
如果你的意思是要求一个文件,为什么不检查require
的输出呢?
require 'already/loaded' => false
如果你想要的东西打包, finishing_moves
gem添加一个class_exists?
方法。
class_exists? :Symbol # => true class_exists? :Rails # => true in a Rails app class_exists? :NonexistentClass # => false