Книга: Программирование на языке Ruby

10.2.2. Более сложный маршалинг

10.2.2. Более сложный маршалинг

Иногда мы хотим настроить маршалинг под свои нужды. Такую возможность дают методы _load и _dump. Они вызываются во время выполнения маршалинга, чтобы вы могли самостоятельно реализовать преобразование данных в строку и обратно.

В следующем примере человек получает 5-процентный доход на начальный капитал с момента рождения. Мы не храним ни возраст, ни текущий баланс, поскольку они являются функциями времени.

class Person
 attr_reader :name
 attr_reader :age
 attr_reader :balance
 def initialize(name,birthdate,beginning)
  @name = name
  @birthdate = birthdate
  @beginning = beginning
  @age = (Time.now - @birthdate)/(365*86400)
  @balance = @beginning*(1.05**@age)
 end
 def marshal_dump
  Struct.new("Human",:name,:birthdate,:beginning)
  str = Struct::Human.new(@name, @birthdate, @beginning)
  str
 end
 def marshal_load(str)
  self.instance_eval do
   initialize(str.name, str.birthdate, str.beginning)
  end
 end
 # Прочие методы...
end
p1 = Person.new("Rudy",Time.now - (14 * 365 * 86400), 100)
p [p1.name, p1.age, p1.balance] # ["Rudy", 14.0, 197.99315994394]
str = Marshal.dump(p1)
p2 = Marshal.load(str)
p [p2.name, p2.age, p2.balance] # ["Rudy", 14.0, 197.99315994394]

При сохранении объекта этого типа атрибуты age и balance не сохраняются. А когда объект восстанавливается, они вычисляются заново. Заметьте: метод marshal_load предполагает, что объект существует; это один из немногих случаев, когда метод initialize приходится вызывать явно (обычно это делает метод new).

Оглавление книги


Генерация: 1.161. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз