你有两个问题。
在puts
和(
之间的空格阻止了括号内的列表被解释为参数列表。一旦在方法名后面加上空格,任何参数列表都必须在括号外面,任何带括号的部分必须是一个合法表达式。在Ruby中, (x,y,z)
不是一个合法的单个表达式,所以会出现上述错误。
如果去掉空格,则会得到以下结果:
> puts(x, y = 1, 2)
NameError: undefined local variable or method `x' for main:Object
这是由于您的第二个问题:
语句puts(x,y = 1,2)
被解析为puts(x, y=1, 2)
,也就是说Ruby将其解释为向puts
传递了三个参数:x
是第一个,y=1
是第二个,2
是第三个。由于x
不在赋值的左侧且尚未定义,因此出现上述错误。
使用额外的一组括号将整个赋值作为一个参数进行分组:
> puts((x,y=1,2))
1
2
但请注意,这里传递了一个包含两个项的列表。对于puts
方法没有影响,但是对于区分列表和单个参数的方法会有所不同:
但请注意,这里传递了一个包含两个项的列表。对于puts
方法没有影响,但是对于区分列表和单个参数的方法会有所不同:
> def foo(a,b) puts "a=#{a},b=#{b}" end
> foo((x,y=1,2))
ArgumentError: wrong number of arguments (1 for 2)
那种情况下,您需要一个额外的标点符号——星号运算符:
> foo(*(x,y=1,2))
a=1, b=2
有趣的是,但实际上意义不大的是,一旦您加倍括号,如果您希望,可以将空格放回:
> puts ((x, y = 1, 2))
1
2
但是这会把它们从参数包装器变成只是额外的表达式包装器;你可以在其周围放置任意数量的括号而不改变任何内容。这意味着在foo
的情况下,展开运算符必须放在两组括号之外:
> foo (*(x,y=1,2))
SyntaxError: (irb):24: syntax error, unexpected tSTAR
> foo *((x,y=1,2))
a=1, b=2
在 Ruby 中,如果第一个参数本身包含括号,通常认为不使用无括号形式是不好的风格。根据你的 Ruby 版本,可能会收到有关此类语句的警告,但即使你没有收到警告,最好也使用完全加括号的版本(方法名称后面没有空格)。