Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a class already exists in Ruby

Tags:

class

ruby

You can use Module.const_get to get the constant referred to by the string. It will return the constant (generally classes are referenced by constants). You can then check to see if the constant is a class.

I would do something along these lines:

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

Also, if possible I would always avoid using eval when accepting user input; I doubt this is going to be used for any serious application, but worth being aware of the security risks.


perhaps you can do it with defined?

eg:

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

Note: the Class check is required, for example:

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

To answer the original question:

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

You can avoid having to rescue the NameError from Module.const_get if you are looking the constant within a certain scope by calling Module#const_defined?("SomeClass").

A common scope to call this would be Object, eg: Object.const_defined?("User").

See: "Module".


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

Class names are constants. You can use the defined? method to see if a constant has been defined.

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

You can read more about how defined? works if you're interested.


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

Here's a more succinct version:

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