[英]Ruby Module can't access local variable
Is there anyway to access foo
from GetVar.print_foo
? 无论如何,可以从
GetVar.print_foo
访问foo
吗?
foo = "test"
module GetVar
def self.print_foo
puts foo
end
end
GetVar.print_foo
I was able to get it to work by changing foo
to a constant FOO
, but this is more of a hack and I am looking for a better solution. 我可以通过将
foo
更改为一个恒定的FOO
使其工作,但这更多的是hack,我正在寻找更好的解决方案。 I also can't, or rather prefer not, to make foo
an instance variable @foo
. 我也不能,或者宁愿不喜欢,也不能使
foo
成为实例变量@foo
。
The simple answer is: no, there is no way to access the local variable foo
in the script scope from the method scope of the print_foo
method. 简单的答案是:不,没有办法从
print_foo
方法的方法范围访问脚本范围中的局部变量foo
。 foo
is a local variable, local variables are local to the scope they are defined in, that's why they are called "local" variables, after all. foo
是一个局部变量,局部变量在定义它们的作用域内是局部的,这就是为什么它们被称为“局部”变量的原因。
foo
is defined in the script scope. foo
在脚本作用域中定义。 It is not defined in the method scope of print_foo
, ergo, it cannot be accessed from print_foo
. 它在ergo的
print_foo
的方法范围内print_foo
,因此无法从print_foo
进行访问。
There are four local variable scopes in Ruby: script, module / class definition, method definition, and lambda literal / block body. 在Ruby中有四个局部变量作用域:脚本,模块/类定义,方法定义和lambda文字/块体。 Of these four, script scope, module / class scope, and method scope create new scopes.
在这四个脚本范围,模块/类范围和方法范围中,创建了新的范围。 Lambda literals and blocks, and only those two create nested scopes that can access local variables from their surrounding lexical scopes.
Lambda文字和块, 只有这两个会创建嵌套的作用域,可以从其周围的词法作用域访问局部变量。
So, the only way to get access to foo
in print_foo
is to make sure that print_foo
is defined in a nested scope, ie in a block, and that all the surrounding scopes are also blocks. 因此,在
print_foo
访问foo
的唯一方法是确保在嵌套作用域(即块中)中定义了print_foo
,并且所有周围的作用域也是块。 Thankfully, there is a method for defining methods called Module#define_method
(or in this case actually Object#define_singleton_method
) that takes a block, and there is a method for defining a module called Module::new
that also takes a block: 值得庆幸的是,有一个方法定义了一个名为
Module#define_method
(或者在本例中为Object#define_singleton_method
),该方法带有一个块,还有一个用于定义名为Module::new
的模块的方法,该方法也带有一个块:
Is there anyway to access foo
from GetVar.print_foo
? 无论如何,可以从
GetVar.print_foo
访问foo
吗?
foo = "test"
GetVar = Module.new do
define_singleton_method(:print_foo) do puts foo end
end
GetVar.print_foo
# test
Actually, we don't even need the block form of Module::new
: 实际上,我们甚至不需要
Module::new
的块形式:
foo = "test"
GetVar = Module.new.tap do |m| m.define_singleton_method(:print_foo) do puts foo end end
GetVar.print_foo
# test
Use class_eval
使用
class_eval
class A
@foo = "test"
end
module GetVar
def self.print_foo
A.class_eval do
puts @foo
end
end
end
GetVar.print_foo
#=> "test"
or flattening the scope 或展平范围
foo = "test"
GetVar = Module.new do
# define a class method
define_singleton_method :print_foo do
puts foo
end
end
GetVar.print_foo
#=> "test"
See this question: How to understand the difference between class_eval() and instance_eval()? 看到这个问题: 如何理解class_eval()和instance_eval()之间的区别?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.