1.8.7 не жалуется, что блок получает два параметра, а жалуется на вашу попытку указать значение по умолчанию для второго параметра.Это:
users.collect { |item, value| value << {:name => item} }.flatten
хорошо разбирает в 1.8.7, но, конечно, он падает во время выполнения, потому что value
is nil
.
1.9 разрешает значения по умолчанию для блокааргументы (см. ниже).
Так что нет, документация не ошибается, вы просто используете collect
странным образом, который работает в 1.9.2, потому что он позволяет использовать значение по умолчаниюзначения для аргументов блока.
В любом случае, использование collect
немного запутанно и может не совсем соответствовать тому, о чем вы думаете, вы должны послушать Каспера и просто сделать collect
:
users.collect { |item| { :name => item } }
Но, если у вас есть вещь для <<
и вы хотите использовать ее, несмотря ни на что, вы можете использовать inject
в 1.8.7 и 1.9.2:
users.inject([ ]) { |value, item| value << { :name => item } }
Это бессмысленная сложность.
Вы пробудили мое любопытство, поэтому я обратился к файлам анализатора Ruby за авторитетным справочником.Возможно, бессмысленная занятая работа, но «бессмысленная» и «плохая» - это разные вещи.
1.9.2-p180 parse.y
имеет следующие вещи:
block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
| f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
| f_arg ',' f_block_optarg opt_f_block_arg
/* ... */
f_block_optarg : f_block_opt
f_block_opt : tIDENTIFIER '=' primary_value
Если вы проследите егонемного, вы увидите, что правило block_param
используется для таких вещей, как:
{ |eggs| ... }
{ |two_cent, stamp| ... }
{ |where_is, pancakes = 'house'| ... }
и форма do
/ end
.Затем проследите от block_param
до f_block_opt
, и вы увидите, где значения по умолчанию явно разрешены грамматикой.
OTOH, 1.8.7-p248 parse.y
имеет это:
opt_block_var : none
| '|' /* none */ '|'
| tOROP
| '|' block_var '|'
В block_var
нет ничего, что позволяло бы использовать значения по умолчанию для аргументов блока.tOROP
только для того, чтобы разрешить обе эти формы:
{ | | pancakes } # '|' /* none */ '|'
{ || pancakes } # tOROP, the logical "or" operator: ||