Scope
Ruby does not have the characteristics of a nested scope (that is, an internal scope that can see an external scope), its scope is completely separate, and once you enter a new scope, the original binding is replaced with a new set of bindings.
The program closes the previous scope in three places and opens a new scope, which is:
- class defines classes
- Modules Definition Module
- Method defines def
Above three keywords, each keyword corresponds to a scope gate (enter), the corresponding end corresponds to leave the door.
Flattened scopes
When entering another scope from one scope, the local variable will be invalidated immediately, in order to make the local variable continue to be valid, the method call can be used instead of the scope gate to let one scope see the variable in the other scope so as to achieve the goal. The specific approach is to replace the def,module.new with class.new instead of Class,module#define_method. This approach is called a flattened scope, which means that two scopes are squeezed together.
Sample code (wrong)
My_var = "Success"
class MyClass
puts My_var #这里无法正确打印 "Success"
def My_method
puts My_var #这里无法正确打印 " Success "End"
Sample code (right)
My_var = "Success"
MyClass = class.new do
puts ' #{my_var} in the Class definition '
define_method:my_method do
' #{my_var} In ' method '
end
In some languages, such as Java or C #, there is the concept of an internal scope (inner scope). In an internal scope, you can see the variables in the external scope (outer scope). But Ruby does not have this nested scope concept, its scope is completely separate, once entered a new scope, the original binding will be replaced by a new set of bindings.
In Ruby, the program closes the previous scope in three places and opens a new scope: class definition, module definition, method.
Scope switching occurs whenever a program enters the definition of a class, module, or method. These three boundaries are marked with the Class,module and DEF keywords, each serving as a scope gate (scope Gate).
How do I get bindings across a scope gate? For example, the following code:
My_var = "Hello"
class MyClass
#你希望在这里能打印my_var
def my_method
# ... And here's the end.
When you enter another scope, the local variable is immediately invalidated. If you replace the class keyword with something that is not a scope gate, such as a method, you can get the value of My_var in a closure and pass the closure to the method. The code is as follows:
My_var = "Hello"
MyClass = class.new do
puts "#{my_var} in" The Class definition "
def my_method
# ... How do you print it out here? End End
Use the Module#define_method () method to replace Def with the following code:
My_var = "Hello"
MyClass = class.new do
puts ' #{my_var} in ' Class definition '
define_method:my_method do
puts ' #{my_var} in the ' method ' end
MyClass.new.my_method
Hello in the class definition "Hello in" method
Using methods to override the scope gate, you can let one scope see a variable in another scope, a technique that can be called a "flat scope."
Shared scopes
Define a set of methods in a flattened scope of a variable to ensure that the variable is shared only by a limited number of methods. This approach is called a shared scope.