Autoload #1

Closed
wants to merge 2 commits into from
View
14 lib/bin/store.rb
@@ -25,11 +25,21 @@ def write(key, value, options={})
def read(key, options=nil)
super do
if doc = collection.find_one(:_id => key.to_s, :expires_at => {'$gt' => Time.now.utc})
- doc['raw'] ? doc['value'] : Marshal.load(doc['value'].to_s)
+ autoload_missing_constants do
+ doc['raw'] ? doc['value'] : Marshal.load(doc['value'].to_s)
+ end
end
end
end
+ def autoload_missing_constants
+ yield
+ rescue ArgumentError => error
+ lazy_load ||= Hash.new { |hash, hash_key| hash[hash_key] = true; false }
+ if error.to_s[/undefined class|referred/] && !lazy_load[error.to_s.split.last.sub(/::$/, '').constantize] then retry
+ else raise error end
+ end
+
def delete(key, options=nil)
super do
collection.remove(:_id => key.to_s)
@@ -81,4 +91,4 @@ def counter_key_upsert(key, amount)
}, :upsert => true)
end
end
-end
+end
View
17 spec/bin/store_spec.rb
@@ -97,6 +97,21 @@
it "works with symbol" do
store.read(:foo).should == 'bar'
end
+
+ it "works with not yet loaded classes" do
+ class Klass
+ def initialize(str)
+ @str = str
+ end
+ def say_hello
+ @str
+ end
+ end
+ obj = Klass.new("hello\n")
+ store.write('foo', obj)
+ dump = store.read('foo')
+ dump.say_hello.should == "hello\n"
+ end
end
describe "#delete" do
@@ -207,4 +222,4 @@
end
end
end
-end
+end