]> git.cworth.org Git - sup/commitdiff
share instance variables across successive hook invocations
authorwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Mon, 20 Aug 2007 01:15:01 +0000 (01:15 +0000)
committerwmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Mon, 20 Aug 2007 01:15:01 +0000 (01:15 +0000)
git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@532 5c8cc53c-5e98-4d25-b20a-d8db53a31250

lib/sup/hook.rb

index 11c6323e7c069446bd1affe3434272fd3c6adaf6..3b7cf16ccf8d62772defe7220f0675ff0d3ed833 100644 (file)
@@ -1,20 +1,25 @@
 module Redwood
 
 class HookManager
-
   ## there's probably a better way to do this, but to evaluate a hook
   ## with a bunch of pre-set "local variables" i define a function
   ## per variable and then instance_evaluate the code.
   ##
+  ## how does rails do it, when you pass :locals into a partial?
+  ##
   ## i don't bother providing setters, since i'm pretty sure the
   ## charade will fall apart pretty quickly with respect to scoping.
   ## this is basically fail-fast.
   class HookContext
-    def initialize name, hash
+    def initialize name
       @__name = name
-      hash.each do |k, v|
-        self.class.instance_eval { define_method(k) { v } }
-      end
+      @__locals = {}
+    end
+
+    attr_writer :__locals
+
+    def method_missing m, *a
+      @__locals[m] || super
     end
 
     def say s
@@ -40,6 +45,8 @@ class HookManager
     @dir = dir
     @hooks = {}
     @descs = {}
+    @contexts = {}
+    
     Dir.mkdir dir unless File.exists? dir
 
     self.class.i_am_the_instance self
@@ -47,16 +54,18 @@ class HookManager
 
   def run name, locals={}
     hook = hook_for(name) or return
-    context = HookContext.new name, locals
-
+    context = @contexts[hook] ||= HookContext.new(name)
+    context.__locals = locals
+    
     begin
-      result = eval @hooks[name], context.__binding, fn_for(name)
+      result = context.instance_eval @hooks[name], fn_for(name)
       if result.is_a? String
         log "got return value: #{result.inspect}"
         BufferManager.flash result 
       end
     rescue Exception => e
       log "error running hook: #{e.message}"
+      log e.backtrace.join("\n")
       BufferManager.flash "Error running hook: #{e.message}"
     end
     context.__cleanup