1

クラスの多くのインスタンスを含む2D配列があります。クラスには4つの配列が含まれています。Marshalを使用して2Dアレイを保存し、ディスクとの間でロードしたいと思います。この目的で、クラスを含む他の2D配列でMarshalを正常に使用しましたが、それらのクラスには配列が含まれていませんでした。これが私に問題を与えるクラスの定義です。

class Light
       attr_accessor :R,:G,:B,:A

       def initialize(i)

            @R = Array.new(4, i)
            @G = Array.new(4, i)
            @B = Array.new(4, i)
            @A = Array.new(4, i)

       end

       @R
       @G
       @B
       @A

end

Lightクラスで独自のマーシャル関数を定義してみました。

def marshal_dump
    {'R' => @R,'G' => @G,'B' => @B,'A' => @A}
end


def marshal_load(data)
    self.R = data['R']
    self.G = data['G']
    self.B = data['B']
    self.A = data['A']
end

このクラスを含む2D配列の作成は次のとおりです

def createLightMap(width,height)
     a = Array.new(width) { Light.new(0.7) }
     a.map! { Array.new(height) { Light.new(0.7) } }
     return a
end

@lightMap = createLightMap(10,10)

これが私が保存してロードする方法です

#save
File.open('lightData','w') do |file|
     Marshal.dump(@lightMap, file)
end

#load
@lightMap = if File.exists?('lightData')
                  File.open('lightData','w') do |file|
                       Marshal.load(file)
                  end
             else
                  puts 'no light data found'
             end

ロードすると、「ロード中:ダンプ形式エラー(リンク解除、インデックス:-96)(引数エラー)」というエラーが表示されます。

カスタムダンプ/ロードマーシャル機能を使用した場合と使用しない場合を試しました。私はjruby1.5.1、ruby1.8.7を使用しています

4

1 に答える 1

1

問題はマーシャルのダンプ/ロードではないと思います。おそらくファイルI/Oだけです。これは私にとってはうまく機能します(カスタムマーシャリングなしで):

class Light
  # You might want to downcase these variables as capitalized 
  # variables in Ruby generally denote constants
  attr_accessor :R,:G,:B,:A

  def initialize(i)
    @R = Array.new(4, i)
    @G = Array.new(4, i)
    @B = Array.new(4, i)
    @A = Array.new(4, i)
  end

  def ==(other)
    @R == other.R && @G == other.G && @B == other.B && @A == other.A
  end
end

# Method names are generally underscored / snake cased
# (JRuby is even smart enough to map this to Java's camel casing).
# Also should probably attach this method to a class or module to prevent
# polluting global namespace
def create_light_map(width,height)
  a = Array.new(width) { Light.new(0.7) }
  # Note you don't need explicit returns - the last value evaluated is the return value
  a.map { Array.new(height) { Light.new(0.7) } } # You can also lose the ! on map
end

# Same casing style applies to variables
light_map = create_light_map(10,10)
# => [[#<Light:0x5ec736e4 @A=[0.7, 0.7, 0.7, 0.7], ...

# Note with marshaled data you should probably open file in binary mode
File.open('/tmp/lightData','wb') { |f| f.write(Marshal.dump(light_map)) }
# => 5240

light_map_demarshaled = File.open('/tmp/lightData','rb') { |f| Marshal.load(f.read) }
# => [[#<Light:0x6a2d0483 @A=[0.7, 0.7, 0.7, 0.7], ...

light_map_demarshaled == light_map
# => true
于 2012-04-14T04:35:11.530 に答える