Ruby 结构创建块无法访问块外的变量
Ruby struct creation block cannot access variable outside the block
在这种情况下,访问 Struct 创建块中的 default
变量似乎不起作用:
default = 'test'
A = Struct.new(:a, :b) do
def initialize(*args)
super(*args)
self.b ||= default
end
end
它抛出以下错误:
'initialize': undefined local variable or method `default' for #<struct A a=2, b=nil> (NameError)
有人可以解释为什么会发生这种情况以及是否有解决方法?
(在 Ruby 1.9.3 和 2.1.2 上测试)
default
变量超出了 initialize
方法的范围。如果你想访问它,我建议你将它变成一个常量(将它重命名为 DEFAULT)(除非,也就是说,你计划在程序运行时更改默认值,但我不明白你为什么要这样做, 否则不会这样命名):
DEFAULT = 'test'
A = Struct.new(:a, :b) do
def initialize(*args)
super(*args)
self.b ||= DEFAULT
end
end
a = A.new(1)
p a.b #=> test
这是因为 def
关键字开始新的局部变量作用域,所以 default
局部变量在其中不可见。解决方法是使用define_method
,因为你传递给它的块是闭包:
default = 'test'
A = Struct.new(:a, :b) do
define_method(:initialize) do |*args|
super(*args)
self.b ||= default
end
end
a = A.new
a.b
# => "test"
在这种情况下,访问 Struct 创建块中的 default
变量似乎不起作用:
default = 'test'
A = Struct.new(:a, :b) do
def initialize(*args)
super(*args)
self.b ||= default
end
end
它抛出以下错误:
'initialize': undefined local variable or method `default' for #<struct A a=2, b=nil> (NameError)
有人可以解释为什么会发生这种情况以及是否有解决方法?
(在 Ruby 1.9.3 和 2.1.2 上测试)
default
变量超出了 initialize
方法的范围。如果你想访问它,我建议你将它变成一个常量(将它重命名为 DEFAULT)(除非,也就是说,你计划在程序运行时更改默认值,但我不明白你为什么要这样做, 否则不会这样命名):
DEFAULT = 'test'
A = Struct.new(:a, :b) do
def initialize(*args)
super(*args)
self.b ||= DEFAULT
end
end
a = A.new(1)
p a.b #=> test
这是因为 def
关键字开始新的局部变量作用域,所以 default
局部变量在其中不可见。解决方法是使用define_method
,因为你传递给它的块是闭包:
default = 'test'
A = Struct.new(:a, :b) do
define_method(:initialize) do |*args|
super(*args)
self.b ||= default
end
end
a = A.new
a.b
# => "test"