76 lines
2.7 KiB
Diff
76 lines
2.7 KiB
Diff
|
|
From dbb4df94e5bc6e533fc2ed09b2fd70df39c049c3 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Jeremy Evans <code@jeremyevans.net>
|
||
|
|
Date: Fri, 31 May 2019 09:58:55 -0700
|
||
|
|
Subject: [PATCH] Fix warning when using yield in templates on ruby 2.7
|
||
|
|
|
||
|
|
Take the class of the scope, and pass it through the
|
||
|
|
compilation methods. Call class_eval on the scope's
|
||
|
|
class so that constant lookup works, and switch the
|
||
|
|
singleton class opening to instance_exec.
|
||
|
|
|
||
|
|
This radically simplifies the compiled template method
|
||
|
|
code, and I would guess it speeds it up significantly
|
||
|
|
as well. However, this approach can cause a memory
|
||
|
|
leak if you are creating anonymous classes at runtime
|
||
|
|
and then passing instances of those classes as the scope
|
||
|
|
of the render.
|
||
|
|
---
|
||
|
|
lib/tilt/template.rb | 19 +++++++------------
|
||
|
|
1 file changed, 7 insertions(+), 12 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/lib/tilt/template.rb b/lib/tilt/template.rb
|
||
|
|
index 604ed47..13d08ff 100644
|
||
|
|
--- a/lib/tilt/template.rb
|
||
|
|
+++ b/lib/tilt/template.rb
|
||
|
|
@@ -166,7 +166,7 @@ def prepare
|
||
|
|
def evaluate(scope, locals, &block)
|
||
|
|
locals_keys = locals.keys
|
||
|
|
locals_keys.sort!{|x, y| x.to_s <=> y.to_s}
|
||
|
|
- method = compiled_method(locals_keys)
|
||
|
|
+ method = compiled_method(locals_keys, scope.class)
|
||
|
|
method.bind(scope).call(locals, &block)
|
||
|
|
end
|
||
|
|
|
||
|
|
@@ -231,9 +231,9 @@ def read_template_file
|
||
|
|
end
|
||
|
|
|
||
|
|
# The compiled method for the locals keys provided.
|
||
|
|
- def compiled_method(locals_keys)
|
||
|
|
+ def compiled_method(locals_keys, scope_class=nil)
|
||
|
|
LOCK.synchronize do
|
||
|
|
- @compiled_method[locals_keys] ||= compile_template_method(locals_keys)
|
||
|
|
+ @compiled_method[[scope_class, locals_keys]] ||= compile_template_method(locals_keys, scope_class)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
@@ -247,7 +247,7 @@ def local_extraction(local_keys)
|
||
|
|
end.join("\n")
|
||
|
|
end
|
||
|
|
|
||
|
|
- def compile_template_method(local_keys)
|
||
|
|
+ def compile_template_method(local_keys, scope_class=nil)
|
||
|
|
source, offset = precompiled(local_keys)
|
||
|
|
local_code = local_extraction(local_keys)
|
||
|
|
|
||
|
|
@@ -261,17 +261,12 @@ def compile_template_method(local_keys)
|
||
|
|
method_source << <<-RUBY
|
||
|
|
TOPOBJECT.class_eval do
|
||
|
|
def #{method_name}(locals)
|
||
|
|
- Thread.current[:tilt_vars] = [self, locals]
|
||
|
|
- class << self
|
||
|
|
- this, locals = Thread.current[:tilt_vars]
|
||
|
|
- locals = locals
|
||
|
|
- this.instance_eval do
|
||
|
|
- #{local_code}
|
||
|
|
+ #{local_code}
|
||
|
|
RUBY
|
||
|
|
offset += method_source.count("\n")
|
||
|
|
method_source << source
|
||
|
|
- method_source << "\nend;end;end;end"
|
||
|
|
- Object.class_eval(method_source, eval_file, line - offset)
|
||
|
|
+ method_source << "\nend;end;"
|
||
|
|
+ (scope_class || Object).class_eval(method_source, eval_file, line - offset)
|
||
|
|
unbind_compiled_method(method_name)
|
||
|
|
end
|
||
|
|
|