Ruby 变量值重新分配逻辑

Ruby variable value reassigning logic

所以我尝试使用不同的关键字进行搜索,但要么是我的搜索操作不当,要么是问题太简单了。无论哪种方式,我的问题是我无法理解 Ruby 中的这个逻辑。

x = 5
x = x + 1

所以,如果我理解正确的话,x 会变成 6。这是为什么呢?如果你 "reassign" 字面上的值不会变成 "x + 1" 而与第一行没有任何关系。

谢谢。

右边先求值

Ruby 本身会给你一个 object_id,你可以用它来识别你所有的对象。但是有一个小问题:

x = 'matz'
=> "matz"
y = 'matz'
=> "matz"
[ x.object_id, y.object_id ]
=> [2164843460, 2134818480]

因此 Ruby 解释器识别 object_id 并在该内存位置赋值

解释器从具有最高优先级的运算符开始

运算符按优先顺序应用。

并不是说右边(总是)先求值,而是加法比赋值有更高的优先级。 运行 irb 进行测试。

$ irb
2.2.0 :001 > x      # => the variable 'x' doesn't yet exist.
NameError: undefined local variable or method `x' for main:Object
    from (irb):1
    from /home/mike/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `'
2.2.0 :002 > x = 5  # => Assign x the value 5.
 => 5               # => Evaluating the expression 'x = 5' returns 5
2.2.0 :003 > x      # => and the value of 'x' is 5.
 => 5 
2.2.0 :004 > x = x + 1  # => Addition has higher precedence than 
                        # => assignment. Ruby evaluates 'x + 1', then
                        # => assigns the result to 'x', and finally 
                        # => returns the result.
 => 6 
2.2.0 :005 > x          # => 'x' has the same value as the previous 
                        # => result.
 => 6 
2.2.0 :006 > x + 1      # => This expression returns the value 7.
 => 7 
2.2.0 :007 > x          # => But without the assignment operator (=),
 => 6                   # => the value of 'x' didn't change.

为什么这很重要?因为运算符优先级并不总是按照您认为的方式工作应该

$ irb
2.2.0 :001 > true and false            # => That makes sense.
 => false 
2.2.0 :002 > x = true and false        # => That *seems* to make sense, but
 => false 
2.2.0 :003 > x                         # => 'x' has the value true, because
 => true                               # => assignment has higher 
                                       # => precedence than Boolean 'and'.
2.2.0 :004 > x = (true and false)
 => false 
2.2.0 :005 > x
 => false 
2.2.0 :006 > 

大多数人期望表达式 x = true and false 等价于 x = (true and false),因为他们期望 Ruby 总是首先计算右侧。但是 Ruby 不会那样做。它计算布尔值 and 之前的赋值 (=)。所以表达式 x = true and false 实际上等同于 (x = true) and false.

Ruby's precedence table on SO