使用ruby splat运算符在哪里合法?

时间:2009-04-22 09:58:23

标签: ruby arrays syntax operator-precedence splat

Splats很酷。它们不只是用于爆炸阵列,尽管这很有趣。它们还可以转换为数组并展平数组(请参阅http://github.com/mischa/splat/tree/master以获取它们所做的详尽列表。)

看起来无法对splat执行其他操作,但在1.8.6 / 1.9中,以下代码会抛出“意外的tSTAR”:

foo = bar || *zap #=> unexpected tSTAR

虽然这有效:

foo = *zap || bar #=> works, but of limited value

splat在表达式中出现在哪里?

2 个答案:

答案 0 :(得分:15)

首先,优先权不是问题,因为foo = bar || (*zap)效果不错。一般的经验法则是您无法在splat上执行其他操作。即使像foo = (*zap)这样简单的事情也是无效的。这也适用于1.9。

话虽如此,您期望foo = bar || *zap做什么,如果有效,那与foo = bar || zap不同?即使在a, b = bar || *zap(也不起作用)的情况下,a, b = bar || zap也会完成我认为同样的事情。

这可能有意义的唯一情况是a, b = foo, bar || *zap。您应该会发现a, b = foo, *(bar || zap)涵盖了您希望使用此案例的大多数情况。如果这不能涵盖你的情况,你应该问自己你真正希望通过编写这样一个丑陋的结构来实现什么。


编辑:

在回复您的评论时,*zap || bar相当于*(zap || bar)。这表明了splat的优先级有多低。究竟有多低?我能给你的最好答案是“相当低”。

但是,有一个有趣的例子,请考虑一个方法foo,该方法有三个参数:

def foo(a, b, c)
  #important stuff happens here!
end

foo(*bar = [1, 2, 3])将在赋值后进行splat,并将参数分别设置为1,2和3。将其与foo((*bar = [1, 2, 3]))进行比较,后者会抱怨参数数量错误(1为3)。

答案 1 :(得分:8)

“splat运算符”实际上根本不是运算符,而是Ruby语法中定义的标记。通读grammar.y或BNF形式的Ruby语法*将告诉您允许它作为最后或唯一的参数:

  • 在方法定义中(可选的最后&foo除外)
  • 在方法调用中(可选的最后&foo除外)
  • 作为作业的LHS,例如:a, b, *cs = [1,2,3,4]
  • 关于作业的RHS,例如:a, b, c = 1, 2, *[3,4,5]
  • 在案例陈述的when子句中