手抜き実装なので、まだ色々足りて無さそうな感じがしますが、一旦の目的までは達成出来ています。
名前はChainableHashとしてみました。
コード
class ChainableHash < Hash def method_missing(name, *args, &block) if name[-1] === '=' self[name[0..-2].to_sym] = args.first elsif self.has_key?(name.to_sym) self[name.to_sym] else self[name.to_sym] = self.class.new end end end
使い方
config = ChainableHash.new config.environment = 'development' # environmentキーと値の追加 p config # => {:environment=>"development"} config.capacity.max = 10 # capacityを定義していなくてもそのままmaxまで指定できる config.capacity.min = 5 # minキーの追加も簡単に出来る p config # => {:environment=>"development", :capacity=>{:max=>10, :min=>5}}
ポイント
else self[name.to_sym] = self.class.new end
ここの部分で、キーが存在しなかった場合にChainableHashのインスタンスを値としてセットするようにしています。 このおかげでチェーンが可能になっています。