lib/sup/hook.rb in sup-0.8.1 vs lib/sup/hook.rb in sup-0.9
- old
+ new
@@ -1,48 +1,26 @@
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 = {}
+ @__cache = {}
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
if BufferManager.instantiated?
@__say_id = BufferManager.say s, @__say_id
BufferManager.draw_screen
else
log s
end
end
def log s
- Redwood::log "hook[#@__name]: #{s}"
+ info "hook[#@__name]: #{s}"
end
def ask_yes_or_no q
if BufferManager.instantiated?
BufferManager.ask_yes_or_no q
@@ -58,16 +36,28 @@
def set tag, value
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
include Singleton
@@ -77,31 +67,27 @@
@descs = {}
@contexts = {}
@tags = {}
Dir.mkdir dir unless File.exists? dir
-
- self.class.i_am_the_instance self
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
def register name, desc
@descs[name] = desc
@@ -123,33 +109,34 @@
end
end
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.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
+ debug "read '#{name}' from #{fn_for(name)}"
end
+ rescue SystemCallError => e
+ #debug "disabled hook for '#{name}': #{e.message}"
+ nil
+ end
end
@hooks[name]
end
def fn_for name
File.join @dir, "#{name}.rb"
end
def log m
- Redwood::log("hook: " + m)
+ info("hook: " + m)
end
end
end