Ruby 1.8 и 1.9: определение того, является ли одноэлементный класс Ruby подклассом другого класса

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


person Claw    schedule 06.03.2013    source источник


Ответы (1)


Я бы предложил:

class Object; def metaclass; class << self; self; end; end; end

class A; end
class B < A; end

b = B.new

b.metaclass < A.metaclass || b.metaclass < A

Протестировано в Ruby 1.8, 1.9 и 2.0.

person Jacob Lukas    schedule 11.03.2013