テキストで雛形を作って、てきとーにそこに値を埋め込みたい。
埋め込む値は、どっか他から与えられる。
どうすんのかなぁ、と思って、試しに雑に作ってみた。
my_template.rb
class MyTemplate < BasicObject
def initialize(template, parameters={})
@template = template
@parameters = parameters
end
def compile
instance_eval("\"#{@template}\"")
end
def method_missing(name, *args)
return @parameters[name] if @parameters.key?(name)
super
end
end
使い方は、こんな感じ。
第一引数にテンプレートの文字列、第二引数に埋め込みたい値を持ったHashを与える。
sample_code1.rb
template = MyTemplate.new('Hello, #{name}!', { name: 'World' })
template.compile #=> Hello, World!
埋め込みたい値の名前はマルチバイト文字列もやろうと思えばできる。
sample_code2.rb
template = MyTemplate.new('Hello, #{名前}!', { %s"名前": 'World' })
template.compile #=> Hello, World!
BasicObject
のinstance_eval
を使うことで、他の定数やクラスは見えない。
そのため、ある程度は悪いことはできないようにできていそう。
sample_code3.rb
template = MyTemplate.new('Hello, #{Dir.glob("./**/*.rb")}!', { name: 'World' })
template.compile #=> NameError (Dir cannot be autoloaded from an anonymous class or module)
実際のテンプレートエンジンのソースを読んだことないので、これと近いことをしているのかはわかりません。