ただのコラム
(この話を題材にする)環境
$ bin/rails -v Rails 5.2.2
with_indifferent_accessというメソッド
Hashの拡張機能としてAvtiveSupportが用意しているメソッド
rails/hash_with_indifferent_access.rb at master · rails/rails · GitHub
Hashのキー値をsymbolでも文字列でも取得可能にするもの。
hash = { a: "A", "b" => "B" , c: "C"} convert_hash = hash.with_indifferent_access # symbolで設定したものでも、文字列でも取得ができる pp convert_hash["a"] "A" pp convert_hash[:b] "B"
従来使う際に考えてほしいこと
with_indifferent_access
を施されたハッシュを利用する際に悩ましいポイント
このメソッドを通したほうが、 convert_hash["a"]
でも convert_hash[:a]
でも 取れるので一見便利だが普通のコードを書く場合は悩ましい部分ができる。
- このハッシュに内容をセットする側はsymbolで設定すべきか、文字列で設定すべきか悩んでしまう。
- 取り出す際もsymbolと文字列でどっちつかずになる可能性があり、取り出し記述の一貫性が失われる。
ただこの2つの観点はスコープ内でどっちの形式かに寄せてしまえばいいので deep_symbolize_keys
もしくは deep_stringify_keys
を使ってどちらかに全て変えてしまえば憂いはなくなる。
戻り値として with_indifferent_access
のハッシュを使うケースに関して
ではこの with_indifferent_access
を使うケースは何があるかと考えると思い浮かぶのは「メソッドの戻り値などでシンボルでも文字列でも扱えるように with_indifferent_access
を施す」というケースが考えられる。
ただその場合はメソッドの作り手側がある程度どう使われて欲しいかが決めたほうが利用者側も悩まなくて済むのでそちらのほうが先程触れた利用側の憂いも減る。
いまだと deep_****_key
でどちらかに寄せてあげればよさそう
こう考えていくと with_indifferent_access
が強く切望されるケースは少なめなため、deep_****_key
で揃えるほうが処理実態もその変換後の受け取る側もシンプルに考えることができるため、「その with_indifferent_access
はなんでしたいのか」を考えたほうが良さそう。