1

我有一个包含许多类实例的二维数组。该类包含 4 个数组。我想使用 Marshal 将二维数组保存到磁盘或从磁盘加载。我已经成功地将 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 类中定义我自己的 marshal 函数:

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

这是包含此类的二维数组的创建

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)(参数错误)”

我尝试过使用和不使用自定义转储/加载编组功能。我正在使用 jruby 1.5.1,ruby 1.8.7

4

1 回答 1

1

我认为问题不是 Marshal 转储/加载,可能只是文件 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 回答