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. 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
is defined in the script scope. It is not defined in the method scope of print_foo
, ergo, it cannot be accessed from print_foo
.
There are four local variable scopes in Ruby: script, module / class definition, method definition, and lambda literal / block body. 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.
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, i.e. in a block, and that all the surrounding scopes are also blocks. 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:
Is there anyway to access foo
from GetVar.print_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
:
foo = "test"
GetVar = Module.new.tap do |m| m.define_singleton_method(:print_foo) do puts foo end end
GetVar.print_foo
# test