@girng I’ll try to explain it briefly.
There’s the Enumerable(T) module. It depends on an abstract each
method whose job is to yield elements of type T
to a block. Array(T)
for example includes Enumerable(T)
, meaning that each
will yield all of the array’s elements in order to the block
. Relying on the each
method we can define many more methods: select
(use each
and just keep the ones that the block given to select
return true
), all?
(use each
and determine if all the elements yielded to the block given to all?
return true
), etc. max
is also defined in terms of each
: traverse all elements and find the one with the maximum value. I suggest you take a look at Enumerable’s source code.
Now, Hash(K, V)
includes Enumerable({K, V})
. What that means is that if you do:
h = {1 => 'a', 2 => 'b'}
h.each do |x|
p x
end
then x
will be of type {Int32, Char}
, which is syntax sugar for Tuple(Int32, Char)
. That is, a Hash
can be seen as a sequence of key-value tuples.
Then you can do hash.max
and that will return the tuple with the maximum value, considering a hash as a sequence of tuples. Comparing two tuples is comparing their elements in order, the greater one is greater, so {2, 1}
is greater than {1, 10}
(2 > 1), but less than {10, 1}
(2 < 10) and than {2, 3}
(2 == 2 so we move on to the second element and we have that 1 < 10).
Now, there’s something else. You can do:
h = {1 => 'a', 2 => 'b'}
h.each do |key, value|
# ...
end
Huh? But Hash#each
is supposedly yielding a single tuple with two elements, how come it seems it’s yielding two elements? That’s another feature of Crystal, similar to what Ruby does (Ruby does it only for Array, Crystal only for Tuple) where if a block yields a tuple you can unpack the tuple elements in the block like that. So this works too:
a = [{1, 2}, {3, 4}]
a.each do |x, y|
# x, y == 1, 2
# x, y == 3, 4
# ...
end
Letting Hash
be Enumerable
is great because it means we can apply a lot of methods like max
, select
, all?
, etc., to it.
I hope this explained a bit of what’s going on with the max
method on Hash
.