class Foo
def initialize
bar = 10
end
fiz = 5
end
Is there a possibility to get thes开发者_开发百科e local values (outside the class) ?
The local variable in initialize would be lost.
You are able to get the value fiz outside of the class, but only upon defining that class, and recording the return of the definition of the class.
return_of_class_definition = (class A ; fiz = 5 ; end)
would assign the value of fiz to the variable.
You can also use binding
but of course, this means changing the class, which may not be allowed for the exercise.
class A
bin = 15
$binding = binding
end
p eval 'bin', $binding
No. Once a local variable goes out of scope (for bar that is when the initialize
method has run - for fiz
when the end
of the class definition has been reached), it's gone. No trace left.
While a local variable is still in scope you can see it (well, its name) with local_variables
and get and set its value with eval
(though that's definitely not recommended for sanity reasons), but once it's out of scope, that's it. No way to get it back.
In ruby we have something we could call scope gates - places when a program written in ruby leaves the previous scope. Those gates are: class
, module
and method (def
keyword). In other words after class
, module
of def
keyword in the code you're immediately entering into a new scope.
In ruby nested visibility doesn't happen and as soon as you create a new scope, the previous binding will be replaced with a new set of bindings.
For example if you define following class:
x = 1
class MyClass
# you can't access to x from here
def foo
# ...from here too
y = 1
local_variables
end
end
local_variables
method call will return [:y]
. It means that we don't have an access to the x
variable. You can workaround this issue using ruby's technique called Flat Scopes. Basically instead defining a class using class
keyword you can define it using Class.new
and pass a block to this call. Obviously a block can take any local variables from the scope where it was defined since it's a closure!
Our previous example could be rewritten to something like like that:
x = 1
Foo = Class.new do
define_method :foo do
i_can_do_something_with(x)
y = 1
local_variables
end
end
In this case local_variables
will return [:x, :y]
.
精彩评论