Подтвердить что ты не робот

Как проверить, существует ли класс в 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.     ....."
4b9b3361

Ответ 1

Вы можете использовать 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 при принятии ввода пользователя; Я сомневаюсь, что это будет использоваться для любого серьезного приложения, но стоит осознавать риски безопасности.

Ответ 2

возможно, вы можете сделать это с определенным?

например:

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

Ответ 3

Вы можете избежать необходимости генерировать NameError из Module.const_get, если вы ищете константу в определенной области, вызывая Module#const_defined?("SomeClass").

Общей сферой для вызова этого является объект, например: Object.const_defined?("User").

Смотрите: " Module".

Ответ 4

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

Ответ 5

Имена классов - это константы. Вы можете использовать метод defined?, чтобы определить, была ли определена константа.

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

Вы можете узнать больше о том, как defined? работает, если вам интересно.

Ответ 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

Ответ 7

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

Ответ 8

Вот что я иногда делаю, чтобы решить эту проблему. Вы можете добавить следующие методы в класс 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

Ответ 9

Я использовал это, чтобы увидеть, был ли класс загружен во время выполнения:

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

Ответ 10

В одной строке я бы написал:

!!Module.const_get(nameofclass) rescue false

который вернет true, только если данный nameofclass принадлежит определенному классу.

Ответ 11

Я предполагаю, что вы предпримете некоторые действия, если класс не загружен.

Если вы хотите потребовать файл, почему бы просто не проверить вывод require?

require 'already/loaded'  
=> false

Ответ 12

Если вы хотите что-то упакованное, finishing_moves gem добавляет class_exists?.

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