为什么写或不是||?

mbi*_*ras 4 ruby operators

据我所知,优先级有所不同,如另一个答案所示:

p foo = false || true
# => true

p foo = false or true
# => false
Run Code Online (Sandbox Code Playgroud)

但似乎在or和之间存在更多不同的东西||.

例如:

p foo = 42 or raise "Something went wrong with foo"
# => 42
p foo = nil or raise "Something went wrong with foo"
# => Something went wrong with foo (RuntimeError)
p foo = 42 || raise "Something went wrong with foo"
# => syntax error, unexpected tOP_ASGN, expecting end-of-input
Run Code Online (Sandbox Code Playgroud)

我期待得到:

p foo = 42 or raise "Something went wrong with foo"
# => 42
p foo = nil or raise "Something went wrong with foo"
# => Something went wrong with foo (RuntimeError)
p foo = 42 || raise "Something went wrong with foo"
# => Something went wrong with foo (RuntimeError)
Run Code Online (Sandbox Code Playgroud)

但这是一个语法错误.那么发生了什么?

Eri*_*nil 8

理论:

这是Ruby 的优先表.

从这个表中不清楚,但没有括号的Ruby方法调用的优先级低于||=,但高于or.看到这个问题.

因此,对于您的代码,从最高优先级到最低优先级:

  • ||
  • =
  • raise "something"
  • or

表达与 or

foo = 42 or raise "Something went wrong with foo"
Run Code Online (Sandbox Code Playgroud)

首先是= :

( foo = 42 ) or raise "Something went wrong with foo"
Run Code Online (Sandbox Code Playgroud)

然后raise:

( foo = 42 ) or ( raise "Something went wrong with foo" )
Run Code Online (Sandbox Code Playgroud)

然后or:

( ( foo = 42 ) or ( raise "Something went wrong with foo" ) )
Run Code Online (Sandbox Code Playgroud)

表达与 ||

foo = 42 || raise "Something went wrong with foo"
Run Code Online (Sandbox Code Playgroud)

首先是||:

foo = ( 42 || raise ) "Something went wrong with foo"
Run Code Online (Sandbox Code Playgroud)

这是你的语法错误!

你要 :

foo = 42 || (raise "Something went wrong with foo") #=> 42
Run Code Online (Sandbox Code Playgroud)

要么

foo = 42 || raise("Something went wrong with foo")  #=> 42
Run Code Online (Sandbox Code Playgroud)

要不就

foo = 42 || raise 
Run Code Online (Sandbox Code Playgroud)

警告!

当你遇到优先事项时,你应该小心添加另一个putsp没有括号!

例如 :

p [1,2,3].map do |i|
  i*2
end
Run Code Online (Sandbox Code Playgroud)

产出:

#<Enumerator: [1, 2, 3]:map>
Run Code Online (Sandbox Code Playgroud)

即使你可能已经预料到:

[2, 4, 6]
Run Code Online (Sandbox Code Playgroud)