【问题标题】:Why would `reload!` in the Rails console cause "superclass mismatch for class" (Rails 4)为什么 Rails 控制台中的“重新加载!”会导致“类的超类不匹配”(Rails 4)
【发布时间】:2020-04-14 23:36:57
【问题描述】:

当我在 Rails 控制台中运行 reload! 时,出现“类的超类不匹配”错误。我在 ruby​​ 中定义了一些超级简单的类,如下所示:

# base_class.rb
module A
  module B
    module C
      class BaseClass
        def close
          #stub
        end
      end
    end
  end
end

还有:

# more_specific.rb
module A
  module B
    module C
      class MoreSpecific < BaseClass
        def initialize
          # ... 
        end

        def close
        end
      end
    end
  end
end

我可以看到实际上存在问题,因为如果我在这样做之前这样做reload!

A::B::C::MoreSpecific.superclass.equal? A::B::C::BaseClass

我收到true,然后如果我在收到错误后执行此操作,我会收到false。此外,BaseClassobject_id 实际上确实发生了变化。

为什么会发生这种情况?我已经检查了代码库中对 MoreSpecific 类的其他引用,因为我认为这可能会导致 BaseClass 被多次建立为常量,但没有看到任何内容。

什么可能导致A:B:C::BaseClass 的object_id 在reload! 之后切换?

【问题讨论】:

  • 请注意,您使用的是 Rails,而不是纯 Ruby,而且这个问题是关于 Rails 控制台中的 Rails 自动加载行为。

标签: ruby ruby-on-rails-4 inheritance autoload superclass


【解决方案1】:

在没有 Require 语句的情况下自动加载模块

reload! 是 Rails 控制台方法,而不是标准 Ruby 方法。虽然您看到的行为可能还有其他原因,但值得注意的是,more_specific.rb 中的 C 模块在运行时不会 require base_class,并且可能会丢失其查找;如果没有它,Rails 可能不会像您期望的那样autoload 模块。

确保依赖于 BaseClass 的模块包含 require base_class 语句,以便在模块重新加载时执行。如果这不能解决问题,那么您的代码可能还有其他问题,这些问题未在您当前的帖子中显示。

【讨论】:

  • require 语句必须针对特定文件,不是吗?你能举一个例子来说明这个需求可能是什么样的吗?
  • 嗯,Rails 的 autoload 文档在第 9.3 节中说:“永远不需要定义要自动加载的常量的文件”。
猜你喜欢
  • 2016-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 2013-03-23
  • 2014-11-12
  • 2012-08-04
相关资源
最近更新 更多