TypeError: несоответствие суперкласса для класса Word в Ruby
Я создаю класс Word
, и я получаю сообщение об ошибке:
TypeError: несоответствие суперкласса для класса Word
Вот код irb:
irb(main):016:0> class Word
irb(main):017:1> def palindrome?(string)
irb(main):018:2> string == string.reverse
irb(main):019:2> end
irb(main):020:1> end
=> nil
irb(main):021:0> w = Word.new
=> #<Word:0x4a8d970>
irb(main):022:0> w.palindrome?("foobar")
=> false
irb(main):023:0> w.palindrome?("level")
=> true
irb(main):024:0> class Word < String
irb(main):025:1> def palindrome?
irb(main):026:2> self == self.reverse
irb(main):027:2> end
irb(main):028:1> end
TypeError: superclass mismatch for class Word
from (irb):24
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in `start'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in `start'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Ответы
Ответ 1
Правило большого пальца для irb (в любом случае irb
или rails console
)
Если вы дважды создаете тот же класс с наследованием (суперкласс), выйдите из экземпляра irb и создайте его снова. Почему это? Потому что иначе конфликты классов будут происходить.
В вашем случае вы используете Windows (найденный из вопроса), поэтому просто введите exit
в командной строке DOS и снова введите irb
или rails console
и создайте класс Word, и он должен работать. Пожалуйста, дайте мне знать, если это не сработает для вас.
Ответ 2
Причина, по которой она дает ошибку несоответствия суперкласса, состоит в том, что вы уже определили класс Word
как наследуемый от Object
class Word
...
end
В Ruby (как и в большинстве динамических языков) вы можете обезьяна-патч путем повторного открытия определения и изменения класса. Однако в вашем случае, когда вы снова открываете класс, вы также пытаетесь переопределить класс как наследуемый от суперкласса String
.
class Word < String
...
end
Как только класс и его структура наследования определены, вы не можете определить его снова.
Как было сказано несколькими людьми, выход и перезапуск irb позволит вам начать с нуля при определении класса Word
.
Ответ 3
link664 ясно объяснил проблему.
Однако есть более легкое исправление без выхода из irb (и потери всей вашей другой работы).
Вы можете удалить существующее определение класса таким образом.
irb(main):051:0> Object.send(:remove_const, :Word)
и вы можете проверить с помощью:
irb(main):052:0> Word.public_instance_methods
который должен вернуться:
NameError: uninitialized constant Word
from (irb):52
Ответ 4
Простой способ обойти эту проблему - заключить оба класса в разные модули:
> module M
> class Word
> def palindrome?(string)
> string == string.reverse
> end
> end
> end
=> nil
> w = M::Word.new
=> #<Word:0x4a8d970>
> w.palindrome?("foobar")
=> false
> w.palindrome?("level")
=> true
> module N
> class Word < String
> def palindrome?
> self == self.reverse
> end
> end
> end
> N::Word.new("kayak").palindrome?
=> true