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
所以我尝试使用不同的关键字进行搜索,但要么是我的搜索操作不当,要么是问题太简单了。无论哪种方式,我的问题是我无法理解 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