Как я могу определить, наследует ли класс A от класса B без создания экземпляра объекта A в Ruby?

18

Предположим, я хочу определить, наследует ли Admin от ActiveRecord::Base . Один из способов - это Admin.new.kind_of? ActiveRecord::Base , но это создает неиспользуемый объект Admin .

Есть ли простой способ сделать это без создания объекта Admin ?

Спасибо

    
задан Brian 06.03.2011 в 19:55
источник

4 ответа

27

Конечно, просто сравните два класса:

if Admin < ActiveRecord::Base
  # ...
end

Интересно отметить, что в то время как Module#< будет return true , если Admin наследуется от AR::Base , оно вернет false или nil , если это не так. false означает, что это наоборот, в то время как nil для несвязанных классов (например, String < Range возвращает nil ).

    
ответ дан Marc-André Lafortune 06.03.2011 в 19:57
источник
  • +1 Это довольно изящно. –  Jakub Hampl 06.03.2011 в 19:58
  • Ups, слишком поздно :-) –  Julian Maicher 06.03.2011 в 20:00
  • И если вы ищете документацию, как это бывает, класс Class получен из модуля, поэтому: ruby-doc.org/core-1.8.7/classes/Module.html#M000206 –  DigitalRoss 06.03.2011 в 20:15
  • @DigitalRoss: хорошая точка, добавлена ​​ссылка. –  Marc-André Lafortune 06.03.2011 в 20:47
8

Это довольно просто:

Admin < ActiveRecord::Base
=> true
    
ответ дан Julian Maicher 06.03.2011 в 19:59
источник
  • Мне нравится этот, который работает, потому что класс Class получен из модуля. ruby-doc.org/core-1.8.7/classes/Module.html#M000206 –  DigitalRoss 06.03.2011 в 20:13
4
Admin.ancestors.include? ActiveRecord::Base

Хм. Ну, это работает, но мы только что научились лучше. Кажется, что класс Module Ruby> определяет < a href="http://www.ruby-doc.org/core-1.8.7/classes/Module.html#M000206"> оператор < для этой цели , а так как класс Класс происходит от Модуль , , что означает, что < будет непосредственно тестировать производные классы.

    
ответ дан DigitalRoss 06.03.2011 в 20:01
источник
3
Admin.ancestors.includes? ActiveRecord::Base

Для прямой родословной вы также можете использовать

Admin.superclass == ActiveRecord::Base
    
ответ дан Jakub Hampl 06.03.2011 в 19:57
источник
  • Это будет работать, но оно неэффективно, так как оно генерирует массив всех предков, а затем выполняет итерацию через поиск ActiveRecord :: Base. –  Marc-André Lafortune 06.03.2011 в 20:02
  • Ах, да, просто прочитайте источник, и он создает новый рубиновый массив, который немного менее эффективен. Хотя это имеет несколько более легкую читаемость (выяснение «что делает этот код?»). –  Jakub Hampl 06.03.2011 в 20:06