]> git.cworth.org Git - sup/commitdiff
fix proc locals, which must use the old method trick
authorWilliam Morgan <wmorgan-sup@masanjin.net>
Mon, 24 Aug 2009 22:32:39 +0000 (18:32 -0400)
committerWilliam Morgan <wmorgan-sup@masanjin.net>
Mon, 24 Aug 2009 22:32:39 +0000 (18:32 -0400)
For hook locals that are specified as procs (usually for performance
reasons), use methods instead of local variables. Sadly you don't get
all the regular variable semantics, but it is the only option for
delayed evaluation AFAICT.

lib/sup/hook.rb

index 0fa4169ba30ac90f56ec8bcd0090e8c62b84e40e..d3d2ba8fc4b6f88619843512c99dec8c0c94c8cb 100644 (file)
@@ -5,6 +5,7 @@ class HookManager
     def initialize name
       @__say_id = nil
       @__name = name
+      @__cache = {}
     end
 
     def say s
@@ -39,7 +40,18 @@ class HookManager
 
     def __run __hook, __filename, __locals
       __binding = binding
-      eval __locals.map { |k, v| "#{k} = __locals[#{k.inspect}];" }.join, __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
       ret