1.8.7 は、ブロックが 2 つのパラメーターを取得することについて不平を言っているのではなく、2 番目のパラメーターにデフォルト値を提供しようとしていることに不平を言っています。これ:
users.collect { |item, value| value << {:name => item} }.flatten
は 1.8.7 で問題なく解析されますが、もちろん実行時にフォールオーバーしvalueますnil。
1.9 では、ブロック引数の既定値を使用できます (以下を参照)。
いいえ、ドキュメントは間違っていませんcollect。ブロック引数のデフォルト値を許可するため、1.9.2 で動作する奇妙な方法で使用しているだけです。
とにかく、あなたの of の使用collectは少し複雑で、あなたが思っていることをしていないかもしれません。Casper に耳を傾け、単純なcollect.
users.collect { |item| { :name => item } }
しかし、<<何があってもそれを使いたい場合injectは、1.8.7 と 1.9.2 の両方で使用できます。
users.inject([ ]) { |value, item| value << { :name => item } }
しかし、それは無意味な複雑さです。
あなたは私の好奇心を刺激したので、信頼できるリファレンスとして Ruby パーサー ファイルにアクセスしました。意味のない忙しい仕事かもしれませんが、「意味がない」と「悪い」は別物です。
1.9.2-p180parse.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-p248parse.yにはこれがあります:
opt_block_var : none
| '|' /* none */ '|'
| tOROP
| '|' block_var '|'
block_varブロック引数のデフォルト値を許可するものは何もありません。tOROPは、これらの両方の形式を許可するためのものです。
{ | | pancakes } # '|' /* none */ '|'
{ || pancakes } # tOROP, the logical "or" operator: ||