概要
問題
config.yml内にerb記法を書いたが、そのままの文字列で返ってきて困った。
FOO=hello
foo: <%= ENV['FOO'] %>
settings.foo # => '<%= ENV['FOO'] %>'
解決策
読み込むファイルの名称に.erb
を含める。
FOO=hello
foo: <%= ENV['FOO'] %>
settings.foo # => 'hello'
参考資料
Sinatra::ConfigFile自体の使い方は下記。
http://www.sinatrarb.com/contrib/config_file.html
ソースのコメントのほうがより詳細かもしれない。
https://github.com/sinatra/sinatra-contrib/blob/master/lib/sinatra/config_file.rb
詳細
以下自分が調べた際の覚書なので、長々書いたけど結論はもう上に書いたので充分
Herokuとか使ってるとmongoidのmonogoid.ymlとかでデータベース接続の情報を環境変数に設定するので<%= ENV['MONGOHQ_URL'] %>
とか書く。
似たようなことをSinatra::ConfigFileでそのままやってみると下記のようになる。
development:
foo: <%= ENV['FOO'] %>
と、なるのだが、実際settings.foo
とした際に帰ってくる値はまんま文字列として<%= ENV['FOO'] %>
が返ってくる。
いやいや、そうじゃなく、展開した値を返して欲しいのさ、という場合は下記のようにする。
development:
foo: <%= ENV['FOO'] %>
一緒に見えるけど、実はファイル名に.erb
を足している。
ソースよく見りゃ書いてあるんだけど、config_file
メソッドの中で下記のようにしている。
document = IO.read(file)
document = ERB.new(document).result if file.split('.').include?('erb')
yaml = config_for_env(YAML.load(document)) || {}
つまりファイル名を.
で分割した配列(今回なら['config', 'yml', 'erb']
)中に'erb'
があればファイルの内容をERBで処理するけど、含まないならERBで処理しない。
仮にERBの記法で書いてもそのままYAML.loadされるので展開されることなくそのまま文字列として返ってくる。
そりゃまあ、YAMLの記法ではないのだから当たり前といえば当たり前で、Railsとかmongoidがある意味気を利かせてYAMLファイル内にerbが使えるようになっている。
たとえばmongoidのload!
メソッドでは下記のように。
YAML.load(ERB.new(File.new(path).read).result)[env]
なんでSinatra::ConfigFileじゃ上記のようにしていないのか、というのは下記のPull Requestsがまさにのもの。
https://github.com/sinatra/sinatra-contrib/pull/54
英語よくわかんないけど、ファイル名はconfig.erb.ymlよりもconfig.yml.erbがいいよね、というようなことが会話されている。
また、当初は上記のmongoidの例のように問答無用でERB噛ませようとしたみたいだけど、無駄にERBで処理しないほうがよいよね、的なことも会話されてる。
けども下記のIssuesもあったりする。
https://github.com/sinatra/sinatra-contrib/issues/116