首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枚举器:具有两个参数的collect方法

枚举器:具有两个参数的collect方法
EN

Stack Overflow用户
提问于 2011-08-04 14:53:16
回答 2查看 698关注 0票数 1

我有这样的代码:

代码语言:javascript
复制
users = ["foo", "bar"]
users.collect { |item, value = []| value << {:name => item} }.flatten

这就像ruby-1.9.2中的风一样工作:

代码语言:javascript
复制
=> [{:name=>"foo"}, {:name=>"bar"}]

但这在ruby-1.8.7中不起作用,因为它不像collect获取两个参数:

代码语言:javascript
复制
SyntaxError: compile error
(irb):2: syntax error, unexpected '=', expecting '|'
users.collect { |item, value = []| value << {:name => item} }.flatten

Reading the documentation这是真的,collect不需要两个参数,但它在Ruby1.9.2中工作。那么,我是不是遗漏了什么,我的Array/Enumerable正在以某种奇怪的方式打补丁,还是文档有误?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-08-04 15:31:45

我想你漏掉了什么。这就是你想要做的,它在1.9和1.8中都有效:

代码语言:javascript
复制
users.collect { |i| { :name => i } }
票数 5
EN

Stack Overflow用户

发布于 2011-08-04 15:36:42

1.8.7不是在抱怨代码块获取了两个参数,而是在抱怨你试图为第二个参数提供默认值。这一点:

代码语言:javascript
复制
users.collect { |item, value| value << {:name => item} }.flatten

在1.8.7中可以很好地解析,但是,当然,它在运行时会崩溃,因为valuenil

1.9允许块参数的默认值(见下文)。

所以,文档没有错,您只是以一种奇怪的方式使用了collect,这种方式在1.9.2中有效,因为它允许块参数的默认值。

不管怎么说,你对collect的使用有点复杂,而且可能不是你想象的那样,你应该听从Casper的建议,只做一个简单的collect

代码语言:javascript
复制
users.collect { |item| { :name => item } }

但是,如果你对<<感兴趣,并且无论如何都想要使用它,你可以在1.8.7和1.9.2中使用inject

代码语言:javascript
复制
users.inject([ ]) { |value, item| value << { :name => item } }

不过,这是毫无意义的复杂性。

您激起了我的好奇心,所以我去Ruby解析器文件中寻找权威参考。也许没有意义的忙碌工作,但“无意义”和“糟糕”是不同的东西。

1.9.2-p180 parse.y具有以下特性:

代码语言:javascript
复制
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规则用于如下所示:

代码语言:javascript
复制
{ |eggs| ... }
{ |two_cent, stamp| ... }
{ |where_is, pancakes = 'house'| ... }

以及do/end表单。然后从block_param一直追踪到f_block_opt,您将看到语法显式允许使用默认值的位置。

OTOH,1.8.7-p248 parse.y有这样的特性:

代码语言:javascript
复制
opt_block_var : none
              | '|' /* none */ '|'
              | tOROP
              | '|' block_var '|'

block_var中没有允许块参数使用默认值的内容。tOROP就是为了支持这两种形式:

代码语言:javascript
复制
{ | | pancakes }    # '|' /* none */ '|'
{ ||  pancakes }    # tOROP, the logical "or" operator: ||
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6937316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档