My solution would be to automatically create the class (and constant hierarchy, i.e. Foo::Bar::Baz
) and make the class autorespond to attribute access attempts.
class AutoObject
def method_missing(*args,&b)
if args.size == 1
name = args[0]
if instance_variable_defined? "@#{name}"
self.class.send :attr_accessor, name
send(*args)
else
super
end
elsif args.size == 2 && args[0].to_s[/=$/]
name = args[0].to_s[0...-1]
if instance_variable_defined? "@#{name}"
self.class.send :attr_accessor, name
send(*args)
else
super
end
end
end
end
def Marshal.auto_load(data)
Marshal.load(data)
rescue ArgumentError => e
classname = e.message[%r(^undefined class/module (.+)$), 1]
raise e unless classname
classname.split("::").inject(Object) do |outer, inner|
if !outer.const_defined? inner
outer.const_set inner, Class.new(AutoObject)
else
outer.const_get inner
end
end
retry
end
This could easily be extended to log all classes created, and even to determine what instance variables they might have. Which could then aid you in updating the files, perhaps programatically.