Ruby并行赋值

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

有什么问题吗?


尝试不加空格“puts(x,y = 1,2)” - tihom
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方法没有影响,但是对于区分列表和单个参数的方法会有所不同:

但请注意,这里传递了一个包含两个项的列表。对于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 版本,可能会收到有关此类语句的警告,但即使你没有收到警告,最好也使用完全加括号的版本(方法名称后面没有空格)。


5

这应该可以工作

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

1
这会产生一个警告,因为puts(之间有空格。 - toro2k

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

一个括号用于方法调用,另一个用于将赋值作为显式表达式进行修饰。

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 

1

puts是一个方法,你正在尝试将=(赋值语句)的返回值传递给它。为此,你需要用两对括号将其包裹:

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

然而,这会导致代码混乱,应该避免使用。 相反,分两步完成,更容易且更清晰:
x, y = 1, 2
puts x, y

此外,您可以删除puts行而不会影响功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接