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

Splats很酷。 它们不只是用于爆炸arrays,尽管这很有趣。 它们还可以转换为数组并压平数组(请参阅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在表达式中出现在哪里?

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

话虽如此,你期望foo = bar || *zap foo = bar || *zap如果有效,请执行,这与foo = bar || zap foo = bar || zap ? 即使在像a, b = bar || *zap的情况下a, b = bar || *zap a, b = bar || *zap (也不起作用), a, b = bar || zap a, b = bar || zap完成了我认为会是同样的事情。

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


编辑:

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

但是,对于一个有趣的例子,考虑一个带有三个参数的方法foo

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

foo(*bar = [1, 2, 3])将在赋值后展开,并将参数分别设置为1,2和3。 将其与foo((*bar = [1, 2, 3])) ,这将抱怨错误的参数数量(1为3)。

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

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