How to check if a class already exists in Ruby

RubyClass

Ruby Problem Overview


How do I check if a class already exists in Ruby?

My code is:

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

I was thinking of using:

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

Ruby Solutions


Solution 1 - 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.

Solution 2 - Ruby

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")

Solution 3 - Ruby

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".

Solution 4 - Ruby

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.

Solution 5 - Ruby

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

Solution 6 - Ruby

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

Solution 7 - Ruby

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

Solution 8 - Ruby

Here's something I sometimes do to tackle this very issue. You can add the following methods to the String class like so:

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

Then:

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

Solution 9 - Ruby

In just one line, I would write:

!!Module.const_get(nameofclass) rescue false

that will return trueonly if the given nameofclass belongs to a defined class.

Solution 10 - Ruby

I used this to see if a class was loaded at runtime:

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

Solution 11 - Ruby

None of the answers above worked for me, maybe because my code lives in the scope of a submodule.

I settled on creating a class_exists? method in my module, using code found in Fred Wilmore's reply to "How do I check if a class is defined?" and finally stopped cursing.

def class_exists?(name)
   name.constantize.is_a?(Class) rescue false # rubocop:disable Style/RescueModifier
end

Full code, for the curious:

module Some
  module Thing
    def self.build(object)
      name = "Some::Thing::#{object.class.name}"
      class_exists?(name) ? name.constantize.new(object) : Base.new(object)
    end

    def self.class_exists?(name)
      name.constantize.is_a?(Class) rescue false # rubocop:disable Style/RescueModifier
    end

    private_class_method :class_exists?
  end
end

I use it as a factory which builds objects depending on the class of the object passed as argument:

Some::Thing.build(something)
=> # A Some::Thing::Base object
Some::Thing.build(something_else)
=> # Another object, which inherits from Some::Thing::Base

Solution 12 - Ruby

If it is a simple standalone class e.g.

class Foo
end

then we can use Object.const_defined?("Foo"). And, if your class is inside any module e.g.

module Bar
  class Foo
  end
end

then we can use Module.const_get("Bar::Foo").

Please note that if Module.const_get('Bar::Foo') doesn't find the class then it will raise exception. While, Object.const_defined?('Foo') will return true or false.

Solution 13 - Ruby

I assume you'll take some action if the class is not loaded.

If you mean to require a file, why not just check the output of require?

require 'already/loaded'  
=> false

Solution 14 - Ruby

If you want something packaged, the finishing_moves gem adds a class_exists? method.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJimmyView Question on Stackoverflow
Solution 1 - RubyOllyView Answer on Stackoverflow
Solution 2 - RubySam SaffronView Answer on Stackoverflow
Solution 3 - RubystcorbettView Answer on Stackoverflow
Solution 4 - RubyTate JohnsonView Answer on Stackoverflow
Solution 5 - RubyRobView Answer on Stackoverflow
Solution 6 - Rubylfender6445View Answer on Stackoverflow
Solution 7 - RubyMike BethanyView Answer on Stackoverflow
Solution 8 - RubyAfz902kView Answer on Stackoverflow
Solution 9 - RubyAndrea SalicettiView Answer on Stackoverflow
Solution 10 - RubyHughView Answer on Stackoverflow
Solution 11 - RubyGoulvenView Answer on Stackoverflow
Solution 12 - RubyNeeraj KumarView Answer on Stackoverflow
Solution 13 - RubystackdumpView Answer on Stackoverflow
Solution 14 - RubyFrank KoehlView Answer on Stackoverflow