From 7a47037e8b16466802749a6a1d0f5063eda5b501 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sat, 27 Aug 2022 11:07:14 -0700 Subject: [PATCH] Use UnboundMethod#bind_call on Ruby 2.7+ bind_call is faster than bind.call, because it doesn't allocate a Method object. --- lib/tilt/template.rb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/tilt/template.rb b/lib/tilt/template.rb index 16944d7..6dc404f 100644 --- a/lib/tilt/template.rb +++ b/lib/tilt/template.rb @@ -167,6 +167,7 @@ def prepare end CLASS_METHOD = Kernel.instance_method(:class) + USE_BIND_CALL = RUBY_VERSION >= '2.7' # Execute the compiled template and return the result string. Template # evaluation is guaranteed to be performed in the scope object with the @@ -177,13 +178,20 @@ def prepare def evaluate(scope, locals, &block) locals_keys = locals.keys locals_keys.sort!{|x, y| x.to_s <=> y.to_s} + case scope when Object - method = compiled_method(locals_keys, Module === scope ? scope : scope.class) + scope_class = Module === scope ? scope : scope.class + else + scope_class = USE_BIND_CALL ? CLASS_METHOD.bind_call(scope) : CLASS_METHOD.bind(scope).call + end + method = compiled_method(locals_keys, scope_class) + + if USE_BIND_CALL + method.bind_call(scope, locals, &block) else - method = compiled_method(locals_keys, CLASS_METHOD.bind(scope).call) + method.bind(scope).call(locals, &block) end - method.bind(scope).call(locals, &block) end # Generates all template source by combining the preamble, template, and