Hash#each
, как и любой другой метод #each
, возвращает один аргумент для блока. В случае Hash#each
этот один аргумент является двухэлементным массивом, состоящим из ключа и значения.
Итак, Hash#each
дает один аргумент, но ваша лямбда имеет два обязательных параметра, поэтому вы получаете ошибку arity.
Он работает с блоками, поскольку блоки менее строги в отношении своих аргументов, и, в частности, если блок имеет несколько параметров, но получает только один аргумент, он попытается деконструировать аргумент, как если бы он был передан с знак.
Существует два вида Proc
с: лямбды и не-лямбды (сбивающие с толку, обычно их также называют Proc
с). Лямбды ведут себя как методы с точки зрения поведения ключевого слова return
и (что более важно для этого случая) того, как они связывают аргументы, тогда как не-лямбда Proc
ведут себя как блоки с точки зрения того, как return
и привязка аргументов работают , Вот почему Proc.new
(который создает не-лямбду Proc
) работает, а lambda
(который явно создает лямбду) - нет.
Вы можете проверить, является ли Proc
лямбда или нет, позвонив по номеру Proc#lambda?
.
Если вы хотите деконструировать аргумент, вам придется делать это явно, так же, как при определении метода:
lambda do |(key, value)|
И, да, более разумный подход к привязке аргументов для блоков, Proc
s и лямбда-выражений был одним из основных обратно несовместимых изменений в Ruby 1.9.