Ошибка типа: несоответствие суперкласса для класса Word в Ruby - PullRequest
24 голосов
/ 22 марта 2012

Я создаю класс 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>'

Ответы [ 4 ]

39 голосов
/ 22 марта 2012

Правило большого пальца для irb (в любом случае irb или rails console)

Если вы создаете один и тот же класс дважды с наследованием (суперкласс), выйдите из экземпляра irb и создайте его снова. Почему это? Потому что в противном случае возникнут классовые конфликты.

В вашем случае вы используете Windows (найдена из вопроса), поэтому просто введите exit в командной строке DOS и снова введите irb или rails console и создайте свой класс Word, и он должен работать. Пожалуйста, дайте мне знать, если это не сработает для вас.

18 голосов
/ 22 марта 2012

Причина, по которой вы получаете ошибку несоответствия суперкласса, состоит в том, что вы уже определили класс Word как наследующий от Object

class Word
...
end

в Ruby (как в большинстве динамических языков).) вы можете monkey-patch классы, заново открыв определение и изменив класс.Однако, в вашем случае, когда вы снова открываете класс, вы также пытаетесь переопределить класс как наследующий от суперкласса String.

class Word < String
...
end

Как только класс и его структура наследования определены, вы не можете определить его снова.

Как уже говорили несколько человек, выход и перезапуск irb позволят вам начать с нуляв определении Word класса.

14 голосов
/ 08 ноября 2013

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
0 голосов
/ 13 августа 2018

Простой способ обойти эту проблему - инкапсулировать оба класса между модулями:

> module M
>     class Word
>         def palindrome?(string)
>             string == string.reverse
>         end
>     end
> end
=> nil
> w = Word.new
=> #<Word:0x4a8d970>
> w.palindrome?("foobar")
=> false
> w.palindrome?("level")
=> true
> module M
>     class Word < String
>         def palindrome?
>             self == self.reverse
>         end
>     end
> end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...