5

我想测试并行赋值的返回值,我写了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

有什么问题吗?

4

5 回答 5

12

你有两个问题。

  1. puts和之间的空格(防止带括号的列表被解释为参数列表。一旦你在方法名后面加了一个空格,任何参数列表都必须在括号之外,并且任何带括号的部分都必须是合法的表达式。在 Ruby 中,(x,y,z)不是一个合法的单一表达式,所以你会得到上面的错误。

    如果你删除空间,你会得到这个:

    > puts(x, y = 1, 2)    
    NameError: undefined local variable or method `x' for main:Object
    

    那是因为你的第二个问题:

  2. 该语句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,但它适用于区分列表和单个参数的方法:

> def foo(a,b) puts "a=#{a},b=#{b}" end
> foo((x,y=1,2))
ArgumentError: wrong number of arguments (1 for 2)

因此,在这种情况下,您还需要一个标点符号 - splat 运算符:

> foo(*(x,y=1,2))   
a=1, b=2

有趣但没有什么实际意义的事实是,一旦将括号加倍,您可以根据需要将空格放回去:

> puts ((x, y = 1, 2))    
1    
2    

但同样,这将它们从参数包装器变成了一个额外的表达式包装器;您可以在不更改任何内容的情况下放置任意数量的括号。这意味着在这种foo情况下,splat 运算符必须超出两组括号:

> foo (*(x,y=1,2))
SyntaxError: (irb):24: syntax error, unexpected tSTAR
> foo *((x,y=1,2))
a=1, b=2

但是,当第一个参数本身包含括号时,通常认为在 Ruby 中使用无括号形式是不好的风格。根据您的 Ruby 版本,您可能会收到有关此类语句的警告,但即使您没有,最好使用全括号版本(方法名称后没有空格)。

于 2013-10-16T12:36:30.063 回答
5

这应该工作

puts( (x, y = 1, 2) )
于 2013-10-16T12:28:48.263 回答
2
puts((x, y = 1, 2))
# >> 1
# >> 2

一组括号用于方法调用,另一组用于将赋值装饰为显式表达式。

于 2013-10-16T12:29:02.067 回答
1

puts是一个接受参数和打印的方法。在方法中,您可以将参数值设置为任何默认值。在您的情况下,它不是并行分配,而是设置默认值。如果你这样做

>puts(a, b = 1, 2)
=> undefined local variable or method `a' for main:Object
from (irb):1

但是如果你设置'a'的值,说'a = 99'然后做

 >puts(a, b = 1, 2)
 99
 1
 2
 => nil 

在 ruby​​ 中,如果您明确指定 '()',则不能在方法名称和开头之间指定空格(

 def hi(x,y,z)
    p x
    p y
    p z
 end
 => nil 

 2.0.0p247 :015 > hi(1,2,3)
 1
 2
 3
 => 3 

 2.0.0p247 :016 > hi (1,2,3)
 SyntaxError: (irb):16: syntax error, unexpected ',', expecting ')'
 hi (1,2,3)
  ^
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/railties-   4.0.0/lib/rails/commands/console.rb:90:in `start'
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'

 2.0.0p247 :017 > hi 1, 2, 3
 1
 2
 3
 => 3 
于 2013-10-16T12:39:56.530 回答
1

puts是一种方法,您正试图将=(赋值)的返回值传递给它。为此,您必须将其包裹在两对括号中:

puts((x, y = 1, 2))

但是,这会导致代码混乱,应该避免。

而是分两步完成,它更容易更清洁:

x, y = 1, 2
puts x, y

此外,您可以在puts不破坏功能的情况下删除该行。

于 2013-10-16T12:40:34.640 回答