gpt4 book ai didi

ruby - 在 ruby 中,为什么没有定义?与 ensure 一起使用时会像预期的那样工作

转载 作者:数据小太阳 更新时间:2023-10-29 07:04:02 25 4
gpt4 key购买 nike

我正在运行 ruby​​ 1.9.2p180(2011-02-18 修订版 30909)[x86_64-linux]。

    #!/usr/bin/env ruby

def ouch()
raise ArgumentError, "woof"
fred = 3
return( nil )

ensure
if ( defined?( fred ) ) then
printf( "fred is defined (%s)\n", fred.inspect() )
else
printf( "fred is not defined\n" )
end

end # ouch()


ouch()

运行时,上述 ruby​​ 脚本的输出非常出乎意料。

    $ ./ouch.rb 
fred is defined (nil)
./ouch.rb:4:in `ouch': woof (ArgumentError)
from ./ouch.rb:22:in `<main>'

所以引发/异常正在发生,fred 没有设置为 3,但是它被定义并设置为零,从而击败了测试定义?()。这非常令人困惑。这是一个错误吗?明明是考试for defined 之后需要测试 not nil。

如果这不是错误,有人可以解释为什么吗?

最佳答案

Ruby 中的局部变量定义在它们首次使用的行和当前词法范围的末尾之间。它们也被隐式初始化为 nil

也考虑这个例子:

if false
var = 123
end
p var # => nil

此行为是有意的。 Ruby 的设计方式是在解析 阶段区分方法调用和局部变量访问,而不是执行阶段。因此,在定义变量之后,对该名称的所有进一步引用都将访问该变量,无论它是否被显式设置为某个值。

(如果有人会指出 Ruby 中的 CALL_VCALL 方法调用类型,我会回答说,据我所知,它仅用于 eval:当您 eval-ing,您无法从一开始就知道是否在 irb 的前一行定义了某个变量,因此应该捕获并相应地分派(dispatch)此类访问。)

关于ruby - 在 ruby 中,为什么没有定义?与 ensure 一起使用时会像预期的那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6974633/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com