【问题标题】:Superclass mismatch, Struct, reloading and Spork超类不匹配、结构、重新加载和 Spork
【发布时间】:2012-04-04 20:30:47
【问题描述】:

假设有以下类

# derp.rb
class Derp < Struct.new :id
end

当我load "./derp.rb" 两次时,程序以TypeError: superclass mismatch for class Derp 失败。好的,这可以通过require 进行管理。但是我怎样才能为每个使用 Spork 运行的测试重新加载这些类呢? require 显然不会工作,因为它会缓存加载的文件。

【问题讨论】:

    标签: ruby class inheritance spork


    【解决方案1】:

    Struct.new 正在为您的每个负载创建新类。

    irb(main):001:0> class Test1 < Struct.new :id; end
    nil
    irb(main):003:0> class Test1 < Struct.new :id; end
    TypeError: superclass mismatch for class Test1
        from (irb):3
        from /usr/bin/irb:12:in `<main>'
    

    您可以将返回的Struct.new 保存到一个变量中,然后您 可以使用那将始终是相同的class

    irb(main):004:0> Id = Struct.new :id
    #<Class:0x00000002c35b20>
    irb(main):005:0> class Test2 < Id; end
    nil
    irb(main):006:0> class Test2 < Id; end
    nil
    

    或者您可以使用Struct.new 块样式代替class 关键字 只会给warning: already initialized constant Test3当你 重新加载你的文件。

    irb(main):023:0> Test3 = Struct.new(:id) do
                         def my_methods
                         "this is a method"
                         end
                       end
    

    【讨论】:

    • 我明白了。但这对 Spork 没有帮助:为每种 Struct 创建常量有点违背目的
    • @synapse Struct.new 总是返回新课程。也许您可以将相同类型的方法(可以使用访问器创建)拆分为模块并 include 它们。
    【解决方案2】:

    您可以确保结构类只创建一次。

    Test1 &lt; $test1 ||= Struct.new(:id)

    【讨论】:

    • 这可行,但会导致警告。像这样的警告:已经初始化常量 WebCalendarHelper::MonthCalendar::HEADER
    【解决方案3】:

    对于那些在 Google 上找到此问题的人,这就是为我解决问题的方法:

    module MyModule
      class MyClass
        MyClassStruct ||= Struct.new(:id)
        SomeStruct < MyClassStruct
        ...
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      相关资源
      最近更新 更多