IMHO, the transform
part of your proposed names don’t seem obvious to me.
In the case where you are adding a new nested value there is no transformation happening at all. In the case of updating a nested value the caller could use the argument of the block to transform the value. Or they might just have the block return something unrelated to the existing value (much like with adding a value).
I.E. transforming seems like a nice feature of such a function but it seems to be a secondary feature and therefore I wouldn’t put it in the name of the method. I would think something like deep_set
or deep_insert
or something might be better.
Separate from naming there is also the question of does having a special method like this provide enough value over the current options in Ruby.
For updating an existing value we can obviously do that pretty well with:
hsh[:a][:b] = 'foo'
Even transforming we can do in limited ways. For example:
hsh[:a][:b].upcase!
hsh[:a][:b] += 1
If the value cannot mutate its state or there isn’t a syntax shortcut like +=
it becomes a bit more verbose:
hsh[:a][:b] = hsh[:a][:b].to_i
While there is a bit of redundancy here it doesn’t seem that the following is significantly better:
hsh.deep_set :a, :b, &:to_i
With regard to deep inserting a new value I think your proposal has more value. There is one existing solution out there to consider. We can use the hash default value to auto-create nested hashes for us:
class RecursiveHash < Hash
def initialize
super() { |h, k| h[k] = RecursiveHash.new }
end
end
With this we can now do things like:
hsh = RecursiveHash.new
hsh[:a][:b] = 'c'
You could even upgrade an existing hash by changing it’s default_proc
:
hsh = {}
hsh.default_proc = proc { |k, v| k[v] = RecursiveHash.new }
hsh[:a][:b] = 'c'
This isn’t really the same thing as what you have designed. It auto-creates hashes as part of the intrinsic nature of the hash vs it being a one-time operation. But there might be overlap between what you have designed and this sort of structure making it a suitable replacement in some situations.
Just my two cents. If such a method was added I wouldn’t find it problematic but I also would probably rarely if ever use it as I don’t think I typically do that sort of deep setting as often as I do deep getting.