为什么这段Ruby代码不起作用?
cached = {}
def cache(*key)
cached[key.join] ||= yield
end
cache("key") do "value" end
我收到以下错误:
NameError:未定义的局部变量或方法`cached' for main:Object
有什么想法吗?
答案 0 :(得分:3)
使用实例变量而不是本地:
@cached = {}
def cache(*key)
@cached[key.join] ||= yield
end
你不能在你的缓存方法中使用本地cached
变量,因为局部变量不存在于方法定义之外,所以如果你之前没有在方法体或方法中定义局部变量,Ruby就找不到它。
有关变量可见性的更多信息here。
答案 1 :(得分:1)
我会尝试补充@ProgNoob的答案。
如果您来自C
或C++
等语言,其中使用代码块创建范围。
{
....
}
该范围内的所有局部变量在外部都不可见,但它们在内部创建的每个范围内都可见,例如:
{
int a = 3;
{
// a is visible inside here
}
// a is visible inside here
...
}
// a is not visible outside the scope
Ruby不会以同样的方式处理事情。当您创建class
,module
或method
时,您正在创建一个全新的范围,而不是从上方范围获取任何内容,就像我们在C
中看到的那样。
v0 = 0
class SomeClass # Scope gate
v1 = 1
# only v1 is visible here
def some_method # Scope gate
v2 = 2
# only v2 is visible here
end # end of def scope gate
end # end of class scope gate
打破范围大门:
Class.new
Module.new
define_method
没有范围门的先前示例
v0 = 0
SomeClass = Class.new do
v1 = 1
# v0 and v1 visible here
define_method(:some_method) do
v2 = 2
# v0, v1 and v2 visible here
end
end
# v0 only visible here