这里发生了什么?两种形式"除非"之间的细微差别是什么?
> irb(main):001:0> foo = true unless defined?(foo)
=> nil
irb(main):002:0> unless defined?(fooo) ; fooo = false ; end
=> false
Run Code Online (Sandbox Code Playgroud)
谢谢
Yan*_*nik 16
显然,ruby在解析时创建局部变量,将它们设置nil为定义,无论代码是否执行,都会执行此操作.
在第一行评估代码时,它不会执行赋值部分,因为foo设置为nil.在第二行中,因为fooo尚未解析,所以defined?返回nil让块内的代码执行并分配fooo.
举个例子,你可以尝试这个:
if false
foo = 43
end
defined? foo
=> "local-variable"
Run Code Online (Sandbox Code Playgroud)
这是从ruby-forum 的论坛帖子中获取的.
FMc*_*FMc 12
让我们从更简单的事情开始:
# z is not yet defined
irb(main):001:0> defined?(z)
=> nil
# Even though the assignment won't execute,
# the mere presence of the assignment statement
# causes z to come to life.
irb(main):002:0> z = 123 if false
=> nil
irb(main):003:0> defined?(z)
=> "local-variable"
irb(main):004:0> z
=> nil
Run Code Online (Sandbox Code Playgroud)
现在我们可以找出你的第一个例子.
foo = true unless defined?(foo)
Run Code Online (Sandbox Code Playgroud)
被foo定义?在我们按ENTER之前irb,没有.但是,赋值语句的存在会导致foo生命.这意味着赋值语句将不会被执行,foo而是存在但具有nil其值.那irb行中评估的最后一个表达式是什么?它是unless defined?(foo),评估为nil.
有关如何分配(甚至那些未执行的分配)导致变量存在的更多信息,请参阅变量/方法歧义的讨论.
在你的第二个例子中,没有任何神秘的东西:fooo未定义,因此块中的代码执行,设置fooo为false.该赋值是最后一个求false值表达式,也就是块的返回值.