ruby 中的变量赋值是如何工作的?
How does variable assignment works in ruby?
Ruby 版本:ruby 2.6.7p197(2021-04-05 修订版 67941)[x86_64-linux]
Railsgem版本:6.0.1
简单的问题,我在rails控制台
上有这个例子
不出所料,如果我尝试调用一个不存在的变量,我会得到一个错误
irb(main):007:0> value
# Traceback (most recent call last):
# 2: from (irb):7
# 1: from (irb):7:in `rescue in irb_binding'
# NameError (undefined local variable or method `value' for main:Object)
但是如果我尝试做下面的例子
(value = 1) if value.present?
它 returns nil 出于某种原因,第一个场景没有括号,我以为它是定义变量然后返回一个 nil 的值,但后来我尝试了它并且发生了再次(我尝试了其他变量,因为 ruby 将其视为已定义变量)
OBS:我在原始 irb 上尝试了相同的场景,但它引发了一个错误,这只发生在 rails 控制台
编辑:它只是引发了一个错误,因为我没有意识到“.present?”是一个 rails 方法,但是如果我将语法更改为
(value = 1) if value
发生同样的行为
为什么会这样?不应该引发 NameError 吗?
Ruby是这样的,请看the docs
The local variable is created when the parser encounters the assignment, not when the assignment occurs:
a = 0 if false # does not assign to a
p local_variables # prints [:a]
p a # prints nil
还有其他有趣的事情:
Another commonly confusing case is when using a modifier if:
p a if a = 0.zero?
Rather than printing “true” you receive a NameError, “undefined local variable or method 'a'”
. Since ruby parses the bare a left of the if first and has not yet seen an assignment to a it assumes you wish to call a method. Ruby then sees the assignment to a and will assume you are referencing a local method.
The confusion comes from the out-of-order execution of the expression. First the local variable is assigned-to then you attempt to call a nonexistent method.
所以你可以
Ruby 版本:ruby 2.6.7p197(2021-04-05 修订版 67941)[x86_64-linux]
Railsgem版本:6.0.1
简单的问题,我在rails控制台
上有这个例子不出所料,如果我尝试调用一个不存在的变量,我会得到一个错误
irb(main):007:0> value
# Traceback (most recent call last):
# 2: from (irb):7
# 1: from (irb):7:in `rescue in irb_binding'
# NameError (undefined local variable or method `value' for main:Object)
但是如果我尝试做下面的例子
(value = 1) if value.present?
它 returns nil 出于某种原因,第一个场景没有括号,我以为它是定义变量然后返回一个 nil 的值,但后来我尝试了它并且发生了再次(我尝试了其他变量,因为 ruby 将其视为已定义变量)
OBS:我在原始 irb 上尝试了相同的场景,但它引发了一个错误,这只发生在 rails 控制台
编辑:它只是引发了一个错误,因为我没有意识到“.present?”是一个 rails 方法,但是如果我将语法更改为
(value = 1) if value
发生同样的行为
为什么会这样?不应该引发 NameError 吗?
Ruby是这样的,请看the docs
The local variable is created when the parser encounters the assignment, not when the assignment occurs:
a = 0 if false # does not assign to a p local_variables # prints [:a] p a # prints nil
还有其他有趣的事情:
Another commonly confusing case is when using a modifier if:
p a if a = 0.zero?
Rather than printing “true” you receive a
NameError, “undefined local variable or method 'a'”
. Since ruby parses the bare a left of the if first and has not yet seen an assignment to a it assumes you wish to call a method. Ruby then sees the assignment to a and will assume you are referencing a local method.The confusion comes from the out-of-order execution of the expression. First the local variable is assigned-to then you attempt to call a nonexistent method.
所以你可以