0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

BasicObjectで雑なテンプレートエンジンみたいなものを作る

Posted at

テキストで雛形を作って、てきとーにそこに値を埋め込みたい。
埋め込む値は、どっか他から与えられる。

どうすんのかなぁ、と思って、試しに雑に作ってみた。

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!

BasicObjectinstance_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)

実際のテンプレートエンジンのソースを読んだことないので、これと近いことをしているのかはわかりません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?