2012-03-20 21 views
6

は、以下のクラススーパークラスのミスマッチ、構造体、および先割れスプーン

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

私は二回プログラムがTypeError: superclass mismatch for class Derpで失敗load "./derp.rb"がありますと仮定します。これはrequireで管理できますしかし、Sporkを使ってテストを実行するたびに、どのようにそのクラスをリロードできますか? requireは、ロードされたファイルをキャッシュするため、明らかに動作しません。

答えて

6

は、あらゆる負荷に対して新しいクラスを作成しています。

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を返されて、あなた はそれが常に同じ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 

またはあなたは、あなたのファイルをリロード とき、それは のみwarning: already initialized constant Test3を与える代わりにclassキーワードのStruct.newブロックのスタイルを使用することができます。

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

。しかし、これはSporkで私を助けません。各種類のStructの定数を作成すると、目的を破ることができます – synapse

+0

@synapse 'Struct.new'は常に新しいクラスを返します。おそらく、同じ型のメソッド(アクセサで作成できる)をモジュールに分割し、それらを 'include'することができます。 –

3

structクラスが1回だけ作成されていることを確認できます。 Googleでこれを見つける人のために

Test1 < $test1 ||= Struct.new(:id)

+0

これは動作しますが、警告が表示されます。この警告のように:既に初期化された定数WebCalendarHelper :: MonthCalendar :: HEADER – rposborne

0

が、これは私のためにそれを解決したものです:私は見

module MyModule 
    class MyClass 
    MyClassStruct ||= Struct.new(:id) 
    SomeStruct < MyClassStruct 
    ... 
    end 
end 
関連する問題