类型错误:Ruby 中 Word 类的超类不匹配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9814282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:55:28  来源:igfitidea点击:

TypeError: superclass mismatch for class Word in Ruby

ruby

提问by AMIC MING

I am creating a Wordclass and I am getting an error:

我正在创建一个Word类,但出现错误:

TypeError: superclass mismatch for class Word

类型错误:Word 类的超类不匹配

Here is the irbcode:

这是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>'

回答by AMIC MING

A thumb rule for irb(either way irbor rails console)

irb的拇指规则(无论是irb还是rails console

If you are creating the same class twice with inheritance (superclass), exit the irb instance and create it again. Why this? Because otherwise class conflicts will happen.

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

In your case, you are using Windows (found from the question), so just type exiton DOS prompt and again type irbor rails consoleand create your Word class and it should work. Please let me know if it doesn't work for you.

在您的情况下,您使用的是 Windows(从问题中找到),因此只需exit在 DOS 提示符下键入,然后再次键入irborrails console并创建您的 Word 类,它应该可以工作。如果它不适合您,请告诉我。

回答by dnatoli

The reason it gives you a superclass mismatch error is because you have already defined the Wordclass as inheriting from Object

它给您一个超类不匹配错误的原因是因为您已经将该Word类定义为从Object继承

class Word
...
end

In Ruby (like in most dynamic languages) you can monkey-patchclasses by reopening the definition and modifying the class. However, in your instance, when you are reopening the class you are also attempting to redefine the class as inheriting from the super class String.

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

class Word < String
...
end

Once a class and it's inheritance structure have been defined, you cannot define it again.

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

As a few people have said, exiting and restarting irb will allow you to start from scratch in defining the Wordclass.

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

回答by ffg

link664 has clearly explained the problem.

link664 已经清楚地解释了这个问题。

However, there's an easier fix without quitting irb (and losing all your other work). You can delete an existing class definition this way.

但是,在不退出 irb(并丢失所有其他工作)的情况下有一个更简单的解决方法。您可以通过这种方式删除现有的类定义。

irb(main):051:0> Object.send(:remove_const, :Word)

and you can verify with:

您可以通过以下方式进行验证:

irb(main):052:0> Word.public_instance_methods

which should return:

应该返回:

NameError: uninitialized constant Word
from (irb):52

回答by Ulysse BN

An easy way to bypass this issue is to encapsulate both classes between different modules:

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

> 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