Ruby变量 #
一、变量概述 #
Ruby是一种动态类型语言,变量不需要声明类型,可以直接赋值使用。变量的类型由赋值的对象决定,并且可以在运行时改变。
ruby
x = 10
x = "hello"
x = [1, 2, 3]
二、变量类型 #
Ruby有五种变量类型,通过前缀区分:
| 类型 | 前缀 | 作用域 | 示例 |
|---|---|---|---|
| 局部变量 | 无 | 方法/块内 | name |
| 实例变量 | @ | 对象内 | @name |
| 类变量 | @@ | 类及子类 | @@count |
| 全局变量 | $ | 整个程序 | $debug |
| 常量 | 大写开头 | 取决于定义位置 | MAX_SIZE |
2.1 局部变量 #
局部变量在方法、块或类定义内部有效。
ruby
def greet
name = "Ruby"
puts "Hello, #{name}"
end
greet
name = "Global"
puts name
[1, 2, 3].each do |n|
result = n * 2
puts result
end
局部变量的作用域规则:
ruby
x = 1
def my_method
x = 10
puts "方法内: #{x}"
end
my_method
puts "方法外: #{x}"
[1, 2, 3].each do |i|
x = i
puts "块内: #{x}"
end
puts "块外: #{x}"
2.2 实例变量 #
实例变量以 @ 开头,属于对象实例,在对象内部共享。
ruby
class Person
def initialize(name, age)
@name = name
@age = age
end
def introduce
puts "我是#{@name},今年#{@age}岁"
end
def name
@name
end
def name=(new_name)
@name = new_name
end
end
person = Person.new("Ruby", 25)
person.introduce
person.name = "Rails"
person.introduce
实例变量的特点:
ruby
class Counter
def increment
@count ||= 0
@count += 1
end
def count
@count || 0
end
end
c1 = Counter.new
c2 = Counter.new
c1.increment
c1.increment
c2.increment
puts c1.count
puts c2.count
2.3 类变量 #
类变量以 @@ 开头,在类及其所有实例、子类之间共享。
ruby
class Animal
@@count = 0
def initialize
@@count += 1
end
def self.count
@@count
end
end
class Dog < Animal
def initialize
super
puts "创建了一只狗"
end
end
class Cat < Animal
def initialize
super
puts "创建了一只猫"
end
end
Dog.new
Cat.new
Dog.new
puts "总共有 #{Animal.count} 只动物"
类变量的注意事项:
ruby
class Parent
@@value = "parent"
def self.value
@@value
end
end
class Child < Parent
@@value = "child"
end
puts Parent.value
puts Child.value
2.4 全局变量 #
全局变量以 $ 开头,在整个程序中可访问。
ruby
$debug = true
def log(message)
puts "[DEBUG] #{message}" if $debug
end
class App
def run
log "应用启动"
end
end
App.new.run
$debug = false
App.new.run
预定义的全局变量:
| 变量 | 含义 |
|---|---|
$0 |
当前脚本名 |
$* |
命令行参数数组 |
$? |
上一个子进程的退出状态 |
$_ |
gets读取的最后一行 |
$. |
当前读取的行号 |
$! |
当前异常信息 |
$@ |
异常的backtrace |
$~ |
最后一次匹配结果 |
$& |
最后一次匹配的字符串 |
$1, $2… |
正则捕获组 |
$stdin |
标准输入 |
$stdout |
标准输出 |
$stderr |
标准错误 |
ruby
puts "脚本名: #{$0}"
puts "参数: #{$*}"
2.5 常量 #
常量以大写字母开头,值不应该被修改。
ruby
MAX_SIZE = 100
DEFAULT_NAME = "Ruby"
PI = 3.14159265359
class Config
VERSION = "1.0.0"
API_URL = "https://api.example.com"
end
puts MAX_SIZE
puts Config::VERSION
常量的警告:
ruby
NAME = "Ruby"
NAME = "Rails"
输出:
text
warning: already initialized constant NAME
冻结常量:
ruby
COLORS = ["red", "green", "blue"].freeze
COLORS << "yellow"
三、变量命名规则 #
3.1 基本规则 #
- 以字母或下划线开头
- 后续可以是字母、数字或下划线
- 区分大小写
ruby
name = "valid"
_name = "valid"
name123 = "valid"
my_name = "valid"
名前 = "valid"
1name = "invalid"
@ = "invalid"
3.2 命名约定 #
ruby
# 局部变量:snake_case
user_name = "Ruby"
total_count = 100
# 实例变量:@snake_case
@user_name = "Ruby"
# 类变量:@@snake_case
@@instance_count = 0
# 全局变量:$snake_case
$global_config = {}
# 常量:SCREAMING_SNAKE_CASE
MAX_CONNECTIONS = 100
DEFAULT_TIMEOUT = 30
# 类/模块名:PascalCase
class UserAccount
end
module PaymentGateway
end
3.3 语义化命名 #
ruby
# 好的命名
user_count = 10
is_active = true
total_price = 99.99
# 不好的命名
x = 10
flag = true
tp = 99.99
四、变量作用域详解 #
4.1 作用域门 #
Ruby有三个作用域门:class、module、def。
ruby
v1 = 1
class MyClass
v2 = 2
def my_method
v3 = 3
end
end
v1可访问
v2不可访问
v3不可访问
4.2 作用域穿透 #
使用 Class.new、Module.new、define_method 可以穿透作用域:
ruby
v1 = 1
MyClass = Class.new do
v2 = 2
puts "类内: v1=#{v1}, v2=#{v2}"
define_method :my_method do
v3 = 3
puts "方法内: v1=#{v1}, v2=#{v2}, v3=#{v3}"
end
end
obj = MyClass.new
obj.my_method
4.3 块的作用域 #
块可以访问外部变量:
ruby
x = 1
[1, 2, 3].each do |n|
puts x
x = n
end
puts x
4.4 Proc和Lambda的作用域 #
ruby
def create_counter
count = 0
-> { count += 1 }
end
counter = create_counter
puts counter.call
puts counter.call
puts counter.call
五、并行赋值 #
5.1 基本并行赋值 #
ruby
a, b = 1, 2
puts a
puts b
a, b = b, a
puts a
puts b
5.2 数组解构 #
ruby
arr = [1, 2, 3]
a, b, c = arr
puts a, b, c
a, *rest = [1, 2, 3, 4, 5]
puts a
p rest
first, *, last = [1, 2, 3, 4, 5]
puts first
puts last
5.3 嵌套解构 #
ruby
a, (b, c) = [1, [2, 3]]
puts a
puts b
puts c
5.4 方法返回多值 #
ruby
def min_max(arr)
[arr.min, arr.max]
end
min, max = min_max([3, 1, 4, 1, 5, 9])
puts "最小值: #{min}, 最大值: #{max}"
六、特殊变量 #
6.1 self #
self 指向当前对象:
ruby
class Person
def initialize(name)
@name = name
end
def introduce
puts "我是 #{self.class} 的实例"
end
def self.create(name)
self.new(name)
end
end
p = Person.new("Ruby")
p.introduce
6.2 nil #
nil 表示"无值":
ruby
x = nil
puts x.nil?
puts x.class
def find_user(id)
nil
end
user = find_user(1)
if user
puts "找到用户"
else
puts "用户不存在"
end
七、变量最佳实践 #
7.1 避免全局变量 #
ruby
# 不好
$counter = 0
def increment
$counter += 1
end
# 好
class Counter
attr_reader :count
def initialize
@count = 0
end
def increment
@count += 1
end
end
7.2 谨慎使用类变量 #
ruby
# 类变量在继承中可能产生意外行为
class Parent
@@value = "parent"
end
class Child < Parent
@@value = "child"
end
# 使用类实例变量替代
class Parent
@value = "parent"
def self.value
@value
end
end
7.3 使用attr系列方法 #
ruby
class Person
attr_reader :name
attr_writer :email
attr_accessor :age
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("Ruby", 25)
puts person.name
person.age = 26
person.email = "ruby@example.com"
八、总结 #
本章我们学习了:
- 变量类型:局部变量、实例变量、类变量、全局变量、常量
- 命名规则:snake_case、PascalCase、SCREAMING_SNAKE_CASE
- 作用域:作用域门、块作用域、闭包
- 并行赋值:解构、交换变量
- 最佳实践:避免全局变量、使用attr方法
接下来让我们学习Ruby的数字类型!
最后更新:2026-03-27