W00t, one of my favourite Perl features can be ported to Ruby in just a single line of code. As everyone knows, in Perl it's possible to write:
$x{a}{b}{c}{d} = "e";
And all intermediate-level hashtables will be created automagically. This is often extremely useful.
On the other hand in lesser languages like Python or Java the only way to set a value in a nested hash is to create intermediate-level hashtables by hand:
x={}
x["a"] = {}
x["a"]["b"] = {}
x["a"]["b"]["c"] = {}
x["a"]["b"]["c"]["d"] = "e"
This may be a small thing, but multi-level hashes are used so often that one actually misses this functionality. For long I thought that Ruby doesn't have autovivification. And well, it doesn't have the full Perl thing, but it can get reasonably close with just this small definition:
def autovivifying_hash
Hash.new {|ht,k| ht[k] = autovivifying_hash}
end
And now you can say:
x = autovivifying_hash
x["a"]["b"]["c"]["d"] = "e"
And that's going to be good enough most of the time :-)
4 comments:
Thank you, I was just looking for this. Perfect solution for me :)
I find this solution more elegant:
h = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
In perl, you can also do
x{1}{'hello'}[4]{7}=5 ... I suppose doing this in ruby would be worse ...
Anonymous: You pretty much never autovivify arrays like that by key assignment in practice, you only do that by pushing at the end of them.
Perl's syntax for push-autovivify is horrible.
Something like: push @{$x{1}{hello}}, {7 => 5}
Post a Comment