Как упоминалось в ответе на предыдущий вопрос, B < A
— это самый простой способ определить, является ли класс подклассом другого. Однако в Ruby 1.8 (также REE 1.8) это не работает, когда B
является одноэлементным классом (т. е. собственным классом). Проиллюстрировать:
class A; end
class B < A; end
b = B.new
B.ancestors # => [B, A, Object, Kernel] (also BasicObject in 1.9)
(class << b; self; end).ancestors # => [B, A, Object, Kernel] (also BasicObject in 1.9)
B < A # => true
(class << b; self; end) < A # => true in 1.9; false in 1.8
Как видите, несмотря на то, что A
указан как предок одноэлементного класса (class << b; self; end
), он возвращает false
, когда вы проверяете, является ли он подклассом A
в Ruby 1.8 (но правильно возвращает true
в 1.9). Следование цепочке #superclass
показывает, почему это так:
B.superclass
# => A
(class << b; self; end).superclass
# => B in 1.9
# => singleton class of B in 1.8
(class << b; self; end).superclass.superclass
# => A in 1.9
# => singleton class of Class in 1.8
Кто-нибудь знает, является ли это ошибкой в 1.8, которая была исправлена в 1.9, или, возможно, ожидаемым поведением, которое было намеренно изменено в 1.9? Я пытался найти упоминание или документацию по этой проблеме в другом месте, но ничего не смог найти.
И из-за этой проблемы кто-нибудь знает, как лучше всего проверить, что класс singleton является подклассом A
в Ruby 1.8? Я использовал (class << b; self; end).ancestors.include?(A)
в качестве обходного пути, хотя технически это не так " правильно", так как список предков также содержит включенные модули.