]> git.cworth.org Git - sup/blobdiff - lib/sup/hook.rb
Merge branch 'hook-local-vars' into next
[sup] / lib / sup / hook.rb
index 74ecfabefc6e69da993b203bbe2e4f717299ce38..48a26d42207f09eaa58df802a3e585ccf14f4f33 100644 (file)
@@ -1,33 +1,10 @@
 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.
-  ## "fail-fast", we'll call it.
   class HookContext
     def initialize name
       @__say_id = nil
       @__name = name
-      @__locals = {}
-    end
-
-    attr_writer :__locals
-
-    def method_missing m, *a
-      case @__locals[m]
-      when Proc
-        @__locals[m] = @__locals[m].call(*a) # only call the proc once
-      when nil
-        super
-      else
-        @__locals[m]
-      end
     end
 
     def say s
@@ -40,7 +17,7 @@ class HookManager
     end
 
     def log s
-      Redwood::log "hook[#@__name]: #{s}"
+      info "hook[#@__name]: #{s}"
     end
 
     def ask_yes_or_no q
@@ -52,12 +29,20 @@ class HookManager
       end
     end
 
-    def __binding 
-      binding
+    def get tag
+      HookManager.tags[tag]
+    end
+
+    def set tag, value
+      HookManager.tags[tag] = value
     end
 
-    def __cleanup
+    def __run __hook, __filename, __locals
+      __binding = binding
+      eval __locals.map { |k, v| "#{k} = __locals[#{k.inspect}];" }.join, __binding
+      ret = eval __hook, __binding, __filename
       BufferManager.clear @__say_id if @__say_id
+      ret
     end
   end
 
@@ -68,27 +53,26 @@ class HookManager
     @hooks = {}
     @descs = {}
     @contexts = {}
-    
-    Dir.mkdir dir unless File.exists? dir
+    @tags = {}
 
-    self.class.i_am_the_instance self
+    Dir.mkdir dir unless File.exists? dir
   end
 
+  attr_reader :tags
+
   def run name, locals={}
     hook = hook_for(name) or return
     context = @contexts[hook] ||= HookContext.new(name)
-    context.__locals = locals
 
     result = nil
     begin
-      result = context.instance_eval @hooks[name], fn_for(name)
+      result = context.__run hook, fn_for(name), locals
     rescue Exception => e
       log "error running hook: #{e.message}"
       log e.backtrace.join("\n")
       @hooks[name] = nil # disable it
       BufferManager.flash "Error running hook: #{e.message}" if BufferManager.instantiated?
     end
-    context.__cleanup
     result
   end
 
@@ -114,19 +98,20 @@ EOS
 
   def enabled? name; !hook_for(name).nil? end
 
+  def clear; @hooks.clear; end
+
 private
 
   def hook_for name
     unless @hooks.member? name
-      @hooks[name] =
-        begin
-          returning IO.readlines(fn_for(name)).join do
-            log "read '#{name}' from #{fn_for(name)}"
-          end
-        rescue SystemCallError => e
-          #log "disabled hook for '#{name}': #{e.message}"
-          nil
+      @hooks[name] = begin
+        returning IO.read(fn_for(name)) do
+          log "read '#{name}' from #{fn_for(name)}"
         end
+      rescue SystemCallError => e
+        #log "disabled hook for '#{name}': #{e.message}"
+        nil
+      end
     end
 
     @hooks[name]
@@ -137,7 +122,7 @@ private
   end
 
   def log m
-    Redwood::log("hook: " + m)
+    info("hook: " + m)
   end
 end