TypeError:Ruby中Word类的超类不匹配



我正在创建一个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>'

irb的经验法则(无论是irb还是rails console

如果您使用继承(超类)创建同一个类两次,请退出irb实例并再次创建它。为什么这样?因为否则就会发生类冲突。

在您的情况下,您使用的是Windows(从问题中找到),所以只需在DOS提示符下键入exit,然后再次键入irbrails console,创建您的Word类,它就可以工作了。如果它对你不起作用,请告诉我。

它给您带来超类不匹配错误的原因是因为您已经将Word类定义为继承自Object

class Word
...
end

在Ruby中(就像在大多数动态语言中一样),您可以通过重新打开定义和修改类来对类进行猴子补丁。但是,在您的实例中,当您重新打开该类时,您还试图将该类重新定义为继承自超类String

class Word < String
...
end

一旦定义了类及其继承结构,就不能再定义它。

正如一些人所说,退出并重新启动irb将允许您从头开始定义Word类。

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

绕过这个问题的一个简单方法是在不同的模块之间封装两个类:

> 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

最新更新