Как проверить, существует ли класс уже в Ruby

Другой случай возможного применения является декоратором, который делегирует все вызовы к обернутому экземпляру. Конкретная реализация декоратора может переопределить только те методы, где функциональность добавляется:

public interface Foo {
    public void bar();
}
public abstract class FooDecorator implements Foo {
    private final Foo wrapped;
    public FooDecorator(Foo wrapped) { this.wrapped = wrapped; }
    public void bar() { wrapped.bar(); }
}
public class TracingFoo extends FooDecorator {
    //Omitting constructor code...
    public void bar() {
        log("Entering bar()");
        super.bar();
        log("Exiting bar()");
    }
}

, Хотя я действительно не вижу necessarity для объявления FooDecorator как краткого обзора (неабстрактный пример: HttpServletRequestWrapper).

61
задан the Tin Man 19 August 2015 в 17:17
поделиться

6 ответов

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

72
ответ дан 24 November 2019 в 17:00
поделиться

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

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

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

8
ответ дан 24 November 2019 в 17:00
поделиться

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

например:

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")
47
ответ дан 24 November 2019 в 17:00
поделиться
defined?(DatabaseCleaner) # => nil
require 'database_cleaner'
defined?(DatabaseCleaner) # => constant
11
ответ дан 24 November 2019 в 17:00
поделиться

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

Обычной областью видимости для этого является Object, например: Object.const_defined?("User").

См: "Module".

27
ответ дан 24 November 2019 в 17:00
поделиться

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

def class_exists?(class_name)
  ObjectSpace.each_object(Class) {|c| return true if c.to_s == class_name }
  false
end
1
ответ дан 24 November 2019 в 17:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: