Techioz Blog

Rubyハッシュでネストされたキーの値を動的に設定する方法

概要

簡単なはずですが、適切な解決策が見つかりませんでした。 第 1 レベルのキーの場合:

resource.public_send("#{key}=", value)

しかし、foo.bar.loloの場合はどうですか?

次のように取得できることはわかっています。

'foo.bar.lolo'.split('.').inject(resource, :send)

または

resource.instance_eval("foo.bar.lolo")

しかし、ネストレベルがわからないと仮定して、最後の変数に値を設定する方法は、2番目または3番目である可能性があります。

すべてのレベルでそれを行う一般的な方法はありますか? 私の例では、次のように実行できます。

resource.public_send("fofo").public_send("bar").public_send("lolo=", value)

解決策

単なる好奇心から、ハッシュについて答えます。

hash = { a: { b: { c: 1 } } }
def deep_set(hash, value, *keys)
  keys[0...-1].inject(hash) do |acc, h|
    acc.public_send(:[], h)
  end.public_send(:[]=, keys.last, value)
end

deep_set(hash, 42, :a, :b, :c)
#⇒ 42
hash
#⇒ { a: { b: { c: 42 } } }