我想测试并行赋值的返回值,我写puts (x, y = 1, 2),但它不起作用,并打印错误消息:
SyntaxError: (irb):74: syntax error, unexpected ',', expecting ')'
puts (x,y =1,2)
^
(irb):74: syntax error, unexpected ')', expecting end-of-input
Run Code Online (Sandbox Code Playgroud)
有什么不对的吗?
Mar*_*eed 12
你有两个问题.
puts和之间的空格(可防止括号列表被解释为参数列表.在方法名称后放置空格后,任何参数列表都必须在括号之外,并且任何带括号的部分必须是合法表达式.在Ruby中,(x,y,z)不是合法的单个表达式,因此您得到上述错误.
如果你删除空格,你得到这个:
> puts(x, y = 1, 2)
NameError: undefined local variable or method `x' for main:Object
Run Code Online (Sandbox Code Playgroud)
那是因为你的第二个问题:
该语句puts(x,y = 1,2)被解析为puts(x, y=1, 2); 也就是说,Ruby将其解释为传递三个参数puts: x第一个y=1是第二个,2第三个是第三个.由于x它不在作业的左侧并且尚未定义,因此您会收到上述错误.
使用一组额外的括号将整个赋值组合为一个参数:
> puts((x,y=1,2))
1
2
Run Code Online (Sandbox Code Playgroud)但请注意,这是传递包含两个项目的单个列表.它没有区别puts,但它将用于区分列表和单个参数的方法:
> def foo(a,b) puts "a=#{a},b=#{b}" end
> foo((x,y=1,2))
ArgumentError: wrong number of arguments (1 for 2)
Run Code Online (Sandbox Code Playgroud)
所以在这种情况下你需要一个标点符号 - splat运算符:
> foo(*(x,y=1,2))
a=1, b=2
Run Code Online (Sandbox Code Playgroud)
有趣但没有实际意义的事实是,一旦你将括号加倍,你可以根据需要放回空间:
> puts ((x, y = 1, 2))
1
2
Run Code Online (Sandbox Code Playgroud)
但是,再一次,它将它们从参数包装器转变为一个额外的表达式包装器; 你可以在不改变任何东西的情况下放置任意数量的括号.这意味着在这种foo情况下,splat运算符必须超出两组括号:
> foo (*(x,y=1,2))
SyntaxError: (irb):24: syntax error, unexpected tSTAR
> foo *((x,y=1,2))
a=1, b=2
Run Code Online (Sandbox Code Playgroud)
然而,当第一个参数本身包含括号时,使用无括号形式的Ruby通常被认为是不好的风格.根据你的Ruby版本,你也许会得到一个这样的言论的警告,但是即使你不这样做,最好是使用完全括号的版本(与方法名称后没有空格).