Rails 3.0.9のようなYAMLファイルをロードしています:
APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__)))
階層的なハッシュのようなすべてのコンテンツをロードします。問題ありません。私が気に入らない部分は、ハッシュには一重引用符または二重引用符でのみアクセスでき、シンボルではアクセスできないという事実です。
APP_CONFIG['mailer']['username'] # works fine
APP_CONFIG[:mailer][:username] # doesn't
何かご意見は?
HashWithIndifferentAccess のようなものを使用してみてください
APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../app.yml', __FILE__))))
別の解決策は、シンボルの前にコロンを付けてアクセスしたいキーを持つことです。例えば:
default: &default
:symbol: "Accessed via a symbol only"
string: "Accessed via a string only"
development:
<<: *default
test:
<<: *default
production:
<<: *default
後で、次のようにこれらにアクセスできます。
APP_CONFIG[:symbol]
APP_CONFIG['string']
YAML::ENGINE.yamler = "syck"
を使用していることに注意してください。これがpsych
で機能するかどうかはわかりません。 (ただし、例で示したように、Psychはキーマージをサポートしません。)
HashWithIndifferentAccess
:の使用について使用すると、重複キーを作成するという副作用があります。1つはシンボルアクセス用、もう1つは文字列アクセス用です。 YAMLデータを配列として渡す場合、これは悪意があるかもしれません。そのソリューションを使用する場合は、このことに注意してください。
Ruby on Railsで作業している場合は、 symbolize_keys() をご覧ください。深く、deep_symbolize_keys()
を使用できます。このアプローチを使用すると、答えは
APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__))).deep_symbolize_keys
これは、選択した回答と同じですが、より良い構文を使用しています。
YAML.load(File.read(file_path)).with_indifferent_access
掘り下げながら発見した別の潜在的な答えがあります。
代わりにYAMLファイルの先頭にこれを追加することにより、HashWithIndifferentAccess.newを省略することができます。
--- !map:HashWithIndifferentAccess
その後、通常のように単純にYAML.loadを実行します。唯一の秘isは、Railsをイニシャライザなどで使用するために環境内でこれを行う場合、既にロードされている必要があるということです。
私はそれを簡単に書くでしょう:
YAML::load_file('app.yml').symbolize_keys
おそらくRailsのparamsハッシュに慣れているでしょう。これは実際には標準のRubyハッシュオブジェクトではなく、HashWithIndifferentAccessです。これにより、 'action'などの文字列または:action toコンテンツにアクセスします。
HashWithIndifferentAccessを使用すると、何を使用しても同じ結果が得られますが、これはHashWithIndifferentAccessオブジェクトでのみ機能することに注意してください。
したがって、YAMLでこれを機能させるには、次のようにYAML.loadの結果をHashWithIndifferentAccessにロードする必要があります。
APP_CONFIG = HashWithIndifferentAccess.new( YAML.load(File.read(File.expand_path('../app.yml', __FILE__))) )
純粋なRuby(つまりRailsなし)を使用している場合は、途中でJSON形式に変更できます。JSONlibのparse
メソッドはキーをシンボル化できます。
http://Ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-parse
ここに私が意味するものがあります:
JSON.parse(JSON.dump(YAML.load_file(File.expand_path('../app.yml', __FILE__))), symbolize_names: true)
注:これにより、jsonとの間の変換のオーバーヘッドが追加されます。
私は通常、混乱を避け、アクセス方法の不整合を防ぐためだけにHashWithIndifferentAccess
を使用しません。そのため、代わりに.deep_symbolize_keys
全体をシンボルキー形式で取得します。