【问题标题】:TypeError: superclass mismatch for class Word in RubyTypeError:Ruby 中 Word 类的超类不匹配
【发布时间】:2019-07-29 20:30:51
【问题描述】:

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

【问题讨论】:

  • 看起来第二个 class Word 与第一个冲突。不知道如何在不关闭 IRB 并重新打开的情况下清除它。
  • 作为一个仅供参考,我倾向于在脚本中执行类、循环和更复杂的块,并运行脚本而不是使用 IRB。
  • 对我们来说也是一个很好的教训,因为这将在任何 Ruby 文件中做同样的事情。谢谢提醒。

标签: ruby


【解决方案1】:

irb 的经验法则(irbrails console

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

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

【讨论】:

  • 这实际上是解决问题的方法吗?是的,如果您退出并重新进入控制台,您可能不会遇到错误,但错误是否表明代码有问题?
  • f you are creating the same class twice with inheritance!是的!我的案子是与装载机有关的。
【解决方案2】:

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

class Word
...
end

在 Ruby 中(就像在大多数动态语言中一样),您可以通过重新打开定义并修改类来monkey-patch 类。但是,在您的实例中,当您重新打开该类时,您还尝试将该类重新定义为从超类 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
    

    【讨论】:

    • 我将此代码插入irb 并得到相同的错误:TypeError: superclass mismatch for class Word
    • 我不太记得我的答案,我想我的意思是使用两个不同的模块名称(M 然后N)。这是我曾经使用的技巧,我会相应地更新我的答案。
    猜你喜欢
    • 2022-11-03
    • 1970-01-01
    • 2022-01-18
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 2017-11-03
    • 2016-02-24
    相关资源
    最近更新 更多