Skip to content

Instantly share code, notes, and snippets.

@rtomayko
Created March 3, 2010 07:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rtomayko/320420 to your computer and use it in GitHub Desktop.
Save rtomayko/320420 to your computer and use it in GitHub Desktop.
# GC on Template finalize
class Template
module CompiledTemplates; end
def self.garbage_collect_compiled_method(object_id)
CompiledTemplates.module_eval do
remove_method Template.compiled_method(object_id)
end
end
def self.compiled_method(object_id)
"__tilt_template_#{object_id}"
end
def initialize(source)
@source = source
ObjectSpace.define_finalizer(self, self.class.method(:garbage_collect_compiled_method))
end
def compiled_method
self.class.compiled_method(object_id)
end
def render(context, locals = {})
unless CompiledTemplates.instance_methods.include?(compiled_method)
CompiledTemplates.module_eval <<-RUBY
def #{compiled_method}(locals)
#{locals.map { |k, v| "#{k} = locals[:#{k}]" }.join("\n")}
#{@source}
end
RUBY
end
# extend context with module if the compiled method is not present
unless context.respond_to?(compiled_method)
context.extend CompiledTemplates
end
context.send(compiled_method, locals)
end
end
template = Template.new('"foo: #{foo}"')
template.render(self, :foo => "bar") # => "foo: bar"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment