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