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.

所以你可以