Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как маршалировать класс в Jruby, который содержит массив

Автор вопроса: SpencerОтветов: 1

У меня есть двумерный массив, содержащий множество экземпляров класса. Класс содержит 4 массива. Я хотел бы сохранить и загрузить 2D-массив на/с диска с помощью Marshal. Я успешно использовал Marshal для этой цели с другими 2D-массивами, содержащими классы, но эти классы не содержали массива. Вот определение класса, доставляющего мне неприятности.

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) (ошибка аргумента)"

Я пробовал с пользовательскими функциями маршала дампа/загрузки и без них. Я использую jruby 1.5.1, рубин 1.8.7

  • Для чего нужны эти голые @R и т. д. в объявлении класса? Dave Newton 12.04.2012
  • Это привычка, оставшаяся от написания кода на C++. Я так понимаю они не нужны? Spencer 12.04.2012
  • На самом деле они ничего делать не будут; объявление класса выполняется по порядку. Итак, attr_accessors создает функции доступа. def объявляет функцию ctor. @X будет просто оцениваться в контексте класса, а не экземпляра, и будет nil, потому что они ничем не инициализированы и совершенно бессмысленны на уровне класса (поскольку они являются экземплярами). переменные). Dave Newton 12.04.2012

rubyarraysserializationmarshallingjruby

Ответы

Ответ 1 · рейтинг 1 · Abe Voelker

Я не думаю, что проблема заключается в дампе/загрузке Marshal, возможно, это просто файловый ввод-вывод. Это отлично работает для меня (без пользовательского маршалинга):

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы