Ruby中使用等于号(=)赋值。如果赋值时变量并没有被使用过,赋值操作会创建一个新的变量。
局部变量命名
必须以字母开始,包含字母、数字和下划线。
局部变量作用域
每个代码块都会创建一个作用域。
局部变量的作用域就是它们定义所在的代码块创建的作用域。局部变量不会泄露到定义所在的代码块创建的作用域。但是,一个代码块创建的作用域会包含外部作用域的局部变量。如:
1.times do
a = 1
puts "local variables in the block: #{local_variables.join ", "}"
end # do end创建了代码块,所以local_variables方法返回的数组包含了局部变量a
puts "no local variables outside the block" if local_variables.empty?
# 上述的local_variables数组是空的,并不包含a,因为代码块中定义的局部变量不会泄露到外部代码块。
Kernel#local_variabls方法返回当前作用域内的局部变量。
局部变量和方法
局部变量的创建发生在Ruby解释器遇到赋值操作的时候,而不是赋值操作发生的时候,如:
a = 0 if false # 不会执行赋值操作,但是会创建局部变量a
p local_variables # 打印 [:a],印证上面的结论
p a # 打印nil,因为并没有对a进行赋值操作
Ruby内,局部变量名和方法名很容易混淆。Ruby是如何区分我们什么时候想调用方法,什么时候想引用局部变量呢?
如果在引用标识符之前,并没有对它进行赋值操作,Ruby认为我们想要调用该标识符表示的方法,否则,Ruby认为我们想要访问对应的局部变量。
实例变量
名称必须以@符号开始,对同一个对象的所有方法可见。为初始化的实例变量的值为nil。
类变量
名称必须以@@开始,类变量对当前类,子类及所有类实例可见。如果未初始化访问类变量,会抛出NameError异常。
全局变量
名称必须以$开头,未初始化的全局变量用于nil值。
赋值方法
定义赋值方法需要在方法名后面加等于号(=),如:
class C
def value=(value)
@value = value
end
end
c = C.new
c.value = 42
赋值方法必须应用到对象上,不然,Ruby会认为是对局部变量的赋值操作。
Ruby中通过attr_accessor定义实例变量的getter/setter。
class C
attr_accessor :value
end
赋值方法总是返回赋值的参数
简化赋值
a+=2 # 同a = a + 2, 运算符+, -, *, /, %, **, &, |, ^, <<, >>均可如此使用
a||=0 # value为falsy(nil 或者 false)的时候进行赋值
a&&=1 # value为truthy(非nil或false)的时候赋值
隐式数组赋值
a = 1,2,3 # a的值为[1,2,3]
a = *[1,2,3] # 同上,将数组展开后赋值
a = 1, *[2,3] # a的值为[1,2,3]
多重赋值
a,b = 1,2 # a的值为1,b的值为2
多重赋值可用于交换变量的值,如:
old_value = 1
new_value, old_value = old_value, 2 # new_value的值为1, old_value的值为2
如果赋值操作符右侧的值多余左侧,多余的值会被忽略,如:
a,b = 1,2,3 # a的值为1,b的值为2
可以使用*符号将多余的值组装成数组,如:
a, *b = 1,2,3 # a的值为1,b的值为[2,3]
数组结构
数组结构除了可应用于方法参数,还可用于赋值中,如:
(a,b) = [1,2] # a的值为1,b的值为2
a,(b,c) = 1, [2,3] # a的值为1,b的值为2,c的值为3
a,(b,*c),*d = 1, [2,3,4], 5, 6 # a的值为1,b的值为2,c的值[3,4], d的值为[5,6]