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

61 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")
Run Code Online (Sandbox Code Playgroud)

我在考虑使用:

eval "#{nameofclass}ancestors.     ....."
Run Code Online (Sandbox Code Playgroud)

Oll*_*lly 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
Run Code Online (Sandbox Code Playgroud)

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

  • 对我来说,如果命名的东西也是一个模块,那就太好了。使用`klass.is_a?(类)|| klass.is_a?(模块)`。命名空间限定名称适用于此方法。例如 `class_exists?('Delayed::Worker')` 非常好。 (2认同)

Sam*_*ron 47

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

例如:

if defined?(MyClassName) == 'constant' && MyClassName.class == Class  
   puts "its a class" 
end
Run Code Online (Sandbox Code Playgroud)

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

Hello = 1 
puts defined?(Hello) == 'constant' # returns true
Run Code Online (Sandbox Code Playgroud)

回答原来的问题:

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


stc*_*ett 27

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

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

请参阅:" 模块 ".

  • 如果已加载该类,则仅返回true.>> Object.const_defined?( "MyClass的")#假>> MyClass的MyClass的#>> Object.const_defined?( "MyClass的")#真,这是至少在Rails控制台,因人而异的情况. (10认同)

Rob*_*Rob 11

defined?(DatabaseCleaner) # => nil
require 'database_cleaner'
defined?(DatabaseCleaner) # => constant
Run Code Online (Sandbox Code Playgroud)


Tat*_*son 8

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

defined?(String)    # => "constant"
defined?(Undefined) # => nil
Run Code Online (Sandbox Code Playgroud)

defined?如果您有兴趣,可以阅读更多有关工作原理的信息.

  • 这不适用于定义的?但是,"字符串"确实是个问题. (4认同)

小智 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
Run Code Online (Sandbox Code Playgroud)


lfe*_*445 6

Kernel.const_defined?("Fixnum") # => true
Run Code Online (Sandbox Code Playgroud)

  • 仅当类已加载时才会返回 true ```$rails c test 正在加载测试环境 (Rails 4.2.5.1) 2.2.1 :001 > Kernel.const_define?('ApiProvider') => false 2.2.1 : 002 > ApiProvider => ApiProvider 2.2.1 :003 > Kernel.const_define?('ApiProvider') => true ``` (3认同)

Afz*_*02k 5

为了解决这个问题,我有时会采取一些措施。您可以像下面这样向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
Run Code Online (Sandbox Code Playgroud)

然后:

'String'.to_class
=> String
'unicorn'.to_class
=> nil
'puppy'.is_a_defined_class?
=> false
'Fixnum'.is_a_defined_class?
=> true
Run Code Online (Sandbox Code Playgroud)