Skip to content

Commit

Permalink
Use UnboundMethod#bind_call on Ruby 2.7+
Browse files Browse the repository at this point in the history
bind_call is faster than bind.call, because it doesn't allocate a
Method object.
  • Loading branch information
jeremyevans committed Feb 10, 2023
1 parent e957fe7 commit 7a47037
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions lib/tilt/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 7a47037

Please sign in to comment.