JanGaJan.com

Is fun? JOY!

Gem Reading - Dotenv

dotenvというGemを知ったので覗いてみました。

about dotevn

読む前にどんなものか簡単に確認。

これなに?

環境変数 ENV をファイル管理できるGemです。こちらの記事が参考になりました。

どう使うの?

Gemfile
1
2
# 後でbundle install
gem 'dotenv'

デフォルトでは.envというファイルの中に、

.env
1
2
HOGE=1
FUGA=2

と書いて、.envを読み込むための命令 Dotenv.load を実行すると、 ENV['HOGE']1 を返すようになります。環境変数をわざわざexportコマンドを使ったり、.zshrcといった設定ファイルに書かなくても使えるようになります。
fixtureを見た感じ=じゃなくて、YAMLっぽく:も使えそう。

読んでみる

2つのGem

このGemからは2つのGemを利用できます。

Gemfile
1
2
3
source 'https://rubygems.org'
gemspec :name => 'dotenv'
gemspec :name => 'dotenv-rails'

gemspecファイルも2つあった。
dotenvというGemはこの機能のベース部分。dotenv-railsというGemは、Railsを利用するときに、dotenvを自動で有効にしてくれるラッパーです。それと、このGemにはCLIのスクリプトも包含しています。

dotenv.rb

ここが外部から呼び出すインターフェースのメソッド(load, load!, overload)を定義しています。module Dotenv extend selfとして、これらをmoduleの特異メソッドにしています。
環境変数を定義するファイルをこのメソッドの引数として渡せばいいが、引数なしの場合は .env がデフォルト値となります。

まだ分かっていないのですが、 instrument というメソッドは、 Active Support Instrumentation という機能を使っている。 この機能はRails限定。

reduceが使われているんだけど、inject とどう使い分けするのかなって疑問に思ったらこんな記事がありました。smalltalkとlispの考え方の違いか〜…実際にはaliasだから使う人の好みが出そう。

environment.rb

Dotenv::EnvironmentHashの子クラス。.env内のkey,value情報を自身に格納して、apply or apply! を呼び出すことでENVに設定している。applyメソッドの呼び出しは、dotenv.rbで行っている。Dotenv::Environmentinitializeの一部として.envの読み込みとパースをやってる。

parse.rb

大事なのはcallメソッド。ここで.envの内容がパースされる。正規表現弱いんでこのあたりは宿題…orz
@@substitutionsというクラス変数があるんだけどここにはSubstitutionsのnamespaceにあるクラスの配列が入ってる。.envのvalueに設定できるものとして、

  1. コマンドの出力結果
  2. 変数展開

がある。 1 は Dotenv::Substitutions::Commandで処理し、2 はDotenv::Substitutions::Variableで処理する。 あー、実際にはそうなるように値を設定しているのかな?

Substitutions.constants のところでクラス名が定数だということがわかった。

rails.rb

デフォルトでは、before_configurationのときに、.envを読み込む。dotenvと違い、ファイル名は.env.local,.env.#{Rails.env}もデフォルトで読み込み対象となる。

それと、上述のActive Support Instrumentationをspringによるファイル変更時のENV再設定に利用しているっぽい。この通知の仕組み?をもうちょっと掘り下げてみようかな。

終わりに

英語が堪能は方はこちらが参考になるかも。全然内容が頭の中に入ってこなかったのでもっとリスニング練習しよう。

Comments