From: William Morgan Date: Sun, 23 Aug 2009 17:24:59 +0000 (-0400) Subject: Merge branch 'hook-local-vars' into next X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=bf30feea5c29d1aa5c1b8bbefa2bf4f4e73b1510;hp=20886f4b1d1f92c4db17fbd2639ba47fb8888046;p=sup Merge branch 'hook-local-vars' into next Conflicts: lib/sup/hook.rb --- diff --git a/lib/sup/hook.rb b/lib/sup/hook.rb index 9c48bca..48a26d4 100644 --- a/lib/sup/hook.rb +++ b/lib/sup/hook.rb @@ -1,38 +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 - - ## an annoying gotcha here is that if you try something - ## like var = var.foo(), var will magically get allocated - ## to Nil and method_missing will never get called. You - ## can work around this by calling self.var or simply - ## not assigning it to itself. - 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 @@ -65,12 +37,12 @@ class HookManager HookManager.tags[tag] = value end - def __binding - binding - 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 @@ -91,18 +63,16 @@ class HookManager 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 @@ -134,15 +104,14 @@ private def hook_for name unless @hooks.member? name - @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 + @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]