Guys, how are you?
I’m stuck thinking about how can I save the state of a class. I want to
save the class variables of some classes. Do I have to require to
metaprogramming for this? I mean: save those variables in an object,
then dump it marshaling and then re-construct a class from that object
when is loaded. I’ll try to explain the situation in an example:
class Dog
@@quantity = 5
def self.change_quantity=(n)
@@quantity = n
end
def self.show_quantity
@@quantity
end
end
Dog.change_quantity = 99
File.open(‘anyfile.mrs’, ‘w+’) do |f|
Marshal.dump(Dog, f)
end
Dog.change_quantity = 50
Marshal.load(File.open(‘anyfile.mrs’))
Dog.show_quantity
#=> 50
#I want to show 99
So as you can see I’m very confused. This is probably not the way to do
what I want, do you have any advice for me? The objetive is to save the
“state” of a class, save the values of all his class variables. Thanks.
Damián.
On Sep 12, 2012, at 16:13 , Damin M. Gonzlez [email protected]
wrote:
Guys, how are you?
I’m stuck thinking about how can I save the state of a class. I want to
save the class variables of some classes. Do I have to require to
metaprogramming for this? I mean: save those variables in an object,
then dump it marshaling and then re-construct a class from that object
when is loaded. I’ll try to explain the situation in an example:
Two ways I can think of off of the top of my head:
use maglev-ruby -Mpersistent to run your code and you’re done.
class Dog
@@quantity = 5
def self.change_quantity=(n)
@@quantity = n
end
def self.show_quantity
@@quantity
end
end
Rename your methods to reflect good ruby (def self.quantitiy and def
self.quantity=) and then make them persist your values. Change the
getter to a lazy accessor that will read in the value from disk (or
whatever) and change the setter to persist the change back out.
def self.quantity
@@quantity ||= Marshal.load(…) # or whatever
end
So I guess it’s up to you to iterate over instance_variables:
–8<----
class IVDumper
def initialize(klass) @klass = klass @ivs = {}
klass.instance_variables.each do |k| @ivs[k] = klass.instance_variable_get(k)
end
end
def restore @ivs.each do |k,v| @klass.instance_variable_set(k,v)
end @klass
end
end
def IVDumper(k)
IVDumper.new(k)
end
Dog.change_quantity = 99
File.open(‘anyfile.mrs’, ‘w+’) do |f|
Marshal.dump(IVDumper(Dog), f)
end
Dog.change_quantity = 50
Marshal.load(File.open(‘anyfile.mrs’)).restore
puts Dog.show_quantity # 99
–8<----
You can probably make this more transparent, e.g using _dump/_load
methods in IVDumper