I had two remarks that I thought I'd bring up. The first concerns a
discrepancy between YAML and Marshal. It has to do with the fact that
YAML will not save any classes that were extended into an object:
class Plop
attr_accessor :foo
def initialize(foo) @foo = foo
end
end
module Plip
attr_accessor :bar
def bar @bar || 42
end
end
a = Plop.new(42)
a.extend(Plip)
a.bar # => 42
require 'yaml'
# Looking at the string made by YAML.dump won't show any references
to Plip
b = YAML.load(YAML.dump(a))
b.bar # => NoMethodError
b = Marshal.load(Marshal.dump(a))
b.bar # => 42
The other remark I had was more of a question. I have an object
manager that tracks a whole set of objects (each with their own unique
id). This object manager is able to save and load (currently to YAML,
but that is to be changed soon). However one problem is that that all
the class-types that could be saved have to be known by this object
manager. This results into the following code:
def full_require(dirname)
Dir.foreach(dirname) {|f|
name = "#{dirname}/#{f}"
if File.directory?(name)
full_require(name) unless f =~ /^\..*/
else
require "#{name}"
end
}
end
class ObjectManager
# ...
def load(io)
full_require("lib/virtual")
# Do actual loading
end
# ...
end
Does anyone have any suggestions on how to tackle this problem
differently?
%Q{ However one problem is that that all
the class-types that could be saved have to be known by this > object
manager. This results into the following code: }
I don't see how the code follows. You have what I call "require_all"
defined, thus requiring every file in a directory. Don't see how that
relates to ObjectManager knowing the classes. Or do you just mean that
the classes must already be defined upon loading the stored objects?
The other remark I had was more of a question. I have an object
manager that tracks a whole set of objects (each with their own unique
id). This object manager is able to save and load (currently to YAML,
but that is to be changed soon). However one problem is that that all
the class-types that could be saved have to be known by this object
manager. This results into the following code:
<snip code>
Does anyone have any suggestions on how to tackle this problem
differently?
The following, taken from Ruby's docs, "implements a perverse kind of
autoload facility" which may nevertheless solve a large part of your
problem. The part that it won't solve may be solved by the addition of a
lookup table mapping class names to their respective require paths.
def Object.const_missing(name) @looked_for ||= {}
str_name = name.to_s
raise "Class not found: #{name}" if @looked_for[str_name] @looked_for[str_name] = 1
file = str_name.downcase
require file
klass = const_get(name)
return klass if klass
raise "Class not found: #{name}"
end
I don't see how the code follows. You have what I call "require_all"
> defined, thus requiring every file in a directory. Don't see how
that
> relates to ObjectManager knowing the classes. Or do you just mean
that
> the classes must already be defined upon loading the stored objects?
Yes, that is exactly what I mean. The classes must be defined upon
loading the stored object, which might not be the case.