From: William Morgan Date: Tue, 8 Sep 2009 19:24:34 +0000 (-0400) Subject: Merge branch 'hook-local-vars' X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=aef0216d7f988ab87a3430c9a65210f0d55dfc64;hp=-c;p=sup Merge branch 'hook-local-vars' --- aef0216d7f988ab87a3430c9a65210f0d55dfc64 diff --combined lib/sup/hook.rb index 0c41162,8a51cfe..2d6533d --- a/lib/sup/hook.rb +++ b/lib/sup/hook.rb @@@ -1,33 -1,11 +1,11 @@@ 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 + @__cache = {} end def say s @@@ -40,7 -18,7 +18,7 @@@ end def log s - Redwood::log "hook[#@__name]: #{s}" + info "hook[#@__name]: #{s}" end def ask_yes_or_no q @@@ -60,12 -38,24 +38,24 @@@ HookManager.tags[tag] = value end - def __binding - binding - end - - def __cleanup + def __run __hook, __filename, __locals + __binding = binding + __lprocs, __lvars = __locals.partition { |k, v| v.is_a?(Proc) } + eval __lvars.map { |k, v| "#{k} = __locals[#{k.inspect}];" }.join, __binding + ## we also support closures for delays evaluation. unfortunately + ## we have to do this via method calls, so you don't get all the + ## semantics of a regular variable. not ideal. + __lprocs.each do |k, v| + self.class.instance_eval do + define_method k do + @__cache[k] ||= v.call + end + end + end + ret = eval __hook, __binding, __filename BufferManager.clear @__say_id if @__say_id + @__cache = {} + ret end end @@@ -79,6 -69,8 +69,6 @@@ @tags = {} Dir.mkdir dir unless File.exists? dir - - self.class.i_am_the_instance self end attr_reader :tags @@@ -86,18 -78,16 +76,16 @@@ 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 @@@ -127,15 -117,14 +115,14 @@@ privat 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] @@@ -146,7 -135,7 +133,7 @@@ end def log m - Redwood::log("hook: " + m) + info("hook: " + m) end end