Scope- ruby中变量的作用范围
ruby中变量的作用范围有3种
?
1. Class definitions
2. Modle definitions
3. Method
?
当程序从一个class,或者module,或者method进入(退出)时,作用域就会改变,对应的3个关键字为:class module,和 def, 每一个关键字的位置就是作用域的入口。
?
?
v1 = 1 #top-level scopeclass MyClass #enter class scope v2 = 2 puts local_variables def fun #enter method scope v3 = 3 puts local_variables end puts local_variablesenda = MyClass.newa.funa.funputs local_variables
这段程序中有4个作用域, ?顶层的作用域, 进入class时的作用域, 和两次调用fun时的作用域
?
?class和module的作用域于method的不同,当定义class或者module时,其中的代码会立即执行,也就是作用域会立即形成,而method的作用域是再真正调用时才会形成。
?
当程序从一个作用域跳到另一个作用域时,本地变量就会超出作用域,那么如何让一个变量进入到两个不用的作用域呢?
?
?
my_var = "Success"class MyClass1 puts "#{my_var} in the class definition" def my_method puts "#{my_var} in the method definition" endend
?
这段程序中,想让变量同时作用于class和method,显然,从顶层的作用域到关键字class时,作用域会发生改变,所以在class中?puts "#{my_var} in the class definition" 会抛出异常,undefined local variable or method `my_var', 同样,在方法my_method中也会抛出异常。
?
作用域的改变是再遇到关键字:class ,module,或者 method 时,所以要想让变量能够被使用,就要避免作用域的改变,也就是说,使用其他方法替换掉 class 和 method
?
?
MyClass1 = Class.new do puts "#{my_var} in the class definition" my_var = "" define_method :my_method do puts "#{my_var} in the method definition" endendMyClass1.new.my_method?
这种从在一个作用域中使用另一个作用域中的变量,称之为:flatten the scope 简称: Flat Scope
?
那么,现在假设你想在几个方法中共享一个变量,而不想让其他人来访问这些变量,你就可以这样写:
?
?
def define_methods shared = 0 Kernel.send :define_method, :counter do shared puts shared end Kernel.send :define_method, :inc do |x| shared += x puts shared endenddefine_methodscounterinc(4)counter
?
输出结果为:
?
?
0
4
4
?
这种称之为: Shared Scope
?
?