Skip to content

Instantly share code, notes, and snippets.

@mattvanhorn
Created May 7, 2014 23:45
Show Gist options
  • Save mattvanhorn/b7bc587e6ebb13e7502d to your computer and use it in GitHub Desktop.
Save mattvanhorn/b7bc587e6ebb13e7502d to your computer and use it in GitHub Desktop.
Demo of two ways to pass locals to an ERB template.
require 'erb'
require 'ostruct'
class TemplateContext
def initialize(locals_hash)
locals_hash.each do |key, value|
singleton_class.send(:define_method, key) { value }
end
end
def bound_locals
binding
end
end
class ExampleContext
def template
'foo=<%= foo %> bar=<%= bar %> baz=<%= baz %>'
end
def good
good = TemplateContext.new(foo: 'foo', bar: 'bar', baz: 'baz')
ERB.new(template).result(good.bound_locals)
end
def missing
missing = TemplateContext.new(foo: 'foo', bar: 'bar')
ERB.new(template).result(missing.bound_locals)
end
def shadowed
baz = 'shadowed'
good = TemplateContext.new(foo: 'foo', bar: 'bar', baz: 'baz')
ERB.new(template).result(good.bound_locals)
end
end
class ExampleOStruct
def template
'foo=<%= foo %> bar=<%= bar %> baz=<%= baz %>'
end
def good
good = OpenStruct.new(foo: 'foo', bar: 'bar', baz: 'baz').instance_eval{binding}
ERB.new(template).result(good)
end
def missing
missing = OpenStruct.new(foo: 'foo', bar: 'bar').instance_eval{binding}
ERB.new(template).result(missing)
end
def shadowed
baz = 'shadowed'
shadowed = OpenStruct.new(foo: 'foo', bar: 'bar', baz: 'baz').instance_eval{binding}
ERB.new(template).result(shadowed)
end
end
# Using OStruct can have some bugs...
ExampleOStruct.new.good # => 'foo=foo bar=bar baz=baz'
ExampleOStruct.new.missing # => 'foo=foo bar=bar baz='
ExampleOStruct.new.shadowed # => 'foo=foo bar=bar baz=shadowed'
# That the explicit context doesn't
ExampleContext.new.good # => 'foo=foo bar=bar baz=baz'
ExampleContext.new.missing # => raises error
ExampleContext.new.shadowed # => 'foo=foo bar=bar baz=baz'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment