Also that it maintains insertion order (since Ruby 1.9) opens up more use cases.
Ruby's hash is a Swiss-army knife
31–40 of 81 posts
Re: Ruby's hash is a Swiss-army knife
#32My favorite little-known fact about Ruby hashes is that they respond to `to_proc` and can be used as procs. For example, you can do this: a = { 1 => 'a', 2 => 'b' } [1, 2, 3].map(&a) #=> ['a', 'b', nil]
fib = Hash.new do |k, v|
next 1 if v == 0 || v == 1
k[v-1] + k[v-2]
endRe: Ruby's hash is a Swiss-army knife
#33My favorite little-known fact about Ruby hashes is that they respond to `to_proc` and can be used as procs. For example, you can do this: a = { 1 => 'a', 2 => 'b' } [1, 2, 3].map(&a) #=> ['a', 'b', nil]
I don't quite understand how this code works. Where does the `nil` come from? What operation are we performing on 3 that causes it to return `nil`?
Re: Ruby's hash is a Swiss-army knife
#34Since Ruby 3, the automatic coercion of keywords to a hash—the second example underneath "Passing Hash to Functions" in this post—is considered a legacy style and is generally frowned upon in new code. That is to say, code like the second call to `foo` here: def foo(kwargs = {}) kwargs end foo({k: 1}) # ok: passing hash argument foo(k: 1) # ok: keywords coerced to hash One of the strongest arguments for avoiding this…
Re: Ruby's hash is a Swiss-army knife
#35My favorite little-known fact about Ruby hashes is that they respond to `to_proc` and can be used as procs. For example, you can do this: a = { 1 => 'a', 2 => 'b' } [1, 2, 3].map(&a) #=> ['a', 'b', nil]
But now I'm wondering where that would be a better solution than just using the `Hash#values_at` method...?
Re: Ruby's hash is a Swiss-army knife
#36I've been in Python/Django for about a year now and I really miss Ruby's hash vs the dict. `.dig(:key, :key, :etc)` is so nice to find deeply nested data without blowing up. One thing I don't miss is knowing whether a hash's keys are strings vs symbols. While it's easily solvable, I've definitely lost time only to smack myself that I need to use a str but was always feeding a sym and swore that this should be a sym b…
I don't know ruby and if it's the same, but if you're not using a library like funcy or toolz for a nested get helper, you can do `dict.get('key', {}).get('key2', {}).get('key3')`. Not the prettiest, but can do in a pinch.
Re: Ruby's hash is a Swiss-army knife
#37The mentioned "simple" bit is arguable: as a language's building block, a hash map is relatively complex and specific, since those can be built out of lists (or trees, though lists/arrays may be preferable for efficiency), which can be built out of pairs (product types, cons cells, tuples; unless going for that efficiency, though it can still be pretty efficient with trees). Maybe it is one of those "simple versus easy" mix-ups.
Re: Ruby's hash is a Swiss-army knife
#38Re: Ruby's hash is a Swiss-army knife
#39My favorite little-known fact about Ruby hashes is that they respond to `to_proc` and can be used as procs. For example, you can do this: a = { 1 => 'a', 2 => 'b' } [1, 2, 3].map(&a) #=> ['a', 'b', nil]
One of the most beautiful things in Ruby that I have ever seen is this fibonacci code. fib = Hash.new do |k, v| next 1 if v == 0 || v == 1 k[v-1] + k[v-2] end
fib = Hash.new {|hash, key| hash[key] = key Example: fib[123] # => 22698374052006863956975682
Makes use of memoization.
Re: Ruby's hash is a Swiss-army knife
#40My favorite little-known fact about Ruby hashes is that they respond to `to_proc` and can be used as procs. For example, you can do this: a = { 1 => 'a', 2 => 'b' } [1, 2, 3].map(&a) #=> ['a', 'b', nil]
One of the most beautiful things in Ruby that I have ever seen is this fibonacci code. fib = Hash.new do |k, v| next 1 if v == 0 || v == 1 k[v-1] + k[v-2] end
A = Hash.new { |a,(m,n)| a[[m,n]] = m==0 ? n+1 : n==0 ? a[[m-1,1]] : a[[m-1, a[[m, n-1]]]] }
A[[3,4]] #=> 125
A.inspect #=> ... long
However, the application utility of a self-populating lazily-evaluated lookup structure goes further. A hash with a default function works great as a simple caching wrapper for all manner of results, for example when talking to slow or fine-grained APIs.