在这个例子中,
def foo(x)
if(x > 5)
bar = 100
end
puts bar
end
Run Code Online (Sandbox Code Playgroud)
然后foo(6)输出:100和foo(3)什么都不输出.
但是,如果我将定义更改为
def foo(x)
if(x > 5)
bar = 100
end
puts bob
end
Run Code Online (Sandbox Code Playgroud)
我得到一个"未定义的局部变量或方法"错误.
所以我的问题是为什么当我调用foo(3)并且从未设置bar时我没有收到此错误?
我们定义一个函数foo:
def foo(s)
case s
when'foo'
x = 3
puts x.inspect
when 'bar'
y = 4
puts y.inspect
end
puts x.inspect
puts y.inspect
end
Run Code Online (Sandbox Code Playgroud)
然后我们将其称为如下:
1.9.3p194 :017 > foo('foo')
in foo scope
3
in outer scope
3
nil
=> nil
1.9.3p194 :018 > foo('bar')
in bar scope
3
in outer scope
nil
3
=> nil
Run Code Online (Sandbox Code Playgroud)
为什么函数不会在任何一种情况下抛出关于未注册的局部变量的错误?在第一种情况下,变量y
似乎不应该存在,所以你不能inspect
在外部范围内调用它; 同为x
在第二种情况下.
这是另一个类似的例子:
def test1
x = 5 if false
puts x.inspect
end
def test2
puts x.inspect
end
Run Code Online (Sandbox Code Playgroud)
然后: …
def foo
#bar = nil
if true
bar = 1
else
bar = 2
end
bar #<-- shouldn't this refer to nil since the bar from the if statement is removed from the stack?
end
puts foo # prints "1"
Run Code Online (Sandbox Code Playgroud)
我一直认为你必须创建一个临时变量并将其定义为nil或初始值,以便在if/else语句中定义的变量将保持在if/else语句的范围之外而不会从堆栈中消失?为什么打印1而不是零?
对于其他类型的变量,我使用||=
,但这对布尔值不起作用(x ||= true
即使x先前被赋值为false,也将x指定为true).
我认为这会奏效:
x = true unless defined?(x)
Run Code Online (Sandbox Code Playgroud)
但事实并非如此:出于某种原因,它将x分配给nil.(这里的解释将不胜感激.)
我知道一种有效的方法:
unless defined?(x)
x = true
end
Run Code Online (Sandbox Code Playgroud)
但它相当冗长.有没有更简洁的方法在Ruby中为布尔变量赋值默认值?
def run
...
rescue FooError
...
rescue
...
ensure
...
end
Run Code Online (Sandbox Code Playgroud)
如何仅抑制 FooError 的确保块?