Ruby作用域 #

一、作用域概述 #

作用域定义了变量的可见性和生命周期。Ruby有多种作用域类型。

变量类型 作用域 示例
局部变量 方法/块内 name
实例变量 对象内 @name
类变量 类及子类 @@count
全局变量 整个程序 $debug
常量 取决于定义位置 MAX_SIZE

二、局部变量作用域 #

2.1 方法作用域 #

ruby
def method_a
  x = 1
  puts x
end

def method_b
  x = 2
  puts x
end

method_a
method_b

2.2 块作用域 #

ruby
x = 1

[1, 2, 3].each do |n|
  x = n
  puts "块内: #{x}"
end

puts "块外: #{x}"

2.3 作用域门 #

ruby
v1 = 1

class MyClass
  v2 = 2

  def my_method
    v3 = 3
  end
end

v1可访问
v2不可访问
v3不可访问

2.4 作用域门类型 #

ruby
v1 = 1

class MyClass
  v2 = 2

  module MyModule
    v3 = 3

    def my_method
      v4 = 4
    end
  end
end

三、实例变量作用域 #

3.1 对象作用域 #

ruby
class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end

  def name=(new_name)
    @name = new_name
  end
end

person = Person.new("Ruby")
person.name
person.name = "Rails"

3.2 实例变量默认值 #

ruby
class Example
  def show
    puts @undefined_var
  end
end

Example.new.show

3.3 实例变量检查 #

ruby
class Example
  def initialize
    @name = "Ruby"
  end

  def check
    puts instance_variables
    puts instance_variable_defined?(:@name)
    puts instance_variable_get(:@name)
    instance_variable_set(:@age, 30)
    puts @age
  end
end

Example.new.check

四、类变量作用域 #

4.1 类作用域 #

ruby
class Counter
  @@count = 0

  def initialize
    @@count += 1
  end

  def self.count
    @@count
  end
end

Counter.new
Counter.new
Counter.new
Counter.count

4.2 继承中的类变量 #

ruby
class Parent
  @@value = "parent"

  def self.value
    @@value
  end
end

class Child < Parent
  @@value = "child"
end

Parent.value
Child.value

4.3 类实例变量 #

ruby
class Parent
  @value = "parent"

  def self.value
    @value
  end
end

class Child < Parent
  @value = "child"
end

Parent.value
Child.value

五、全局变量作用域 #

5.1 全局访问 #

ruby
$debug = true

def log(message)
  puts message if $debug
end

class App
  def run
    log "Starting app"
  end
end

App.new.run

5.2 预定义全局变量 #

ruby
puts $0
puts $*
puts $?
puts $stdin
puts $stdout

5.3 全局变量的问题 #

ruby
$counter = 0

def increment
  $counter += 1
end

def reset
  $counter = 0
end

increment
increment
puts $counter
reset
puts $counter

六、常量作用域 #

6.1 类常量 #

ruby
class MathConstants
  PI = 3.14159
  E = 2.71828

  def self.circle_area(radius)
    PI * radius ** 2
  end
end

MathConstants::PI
MathConstants.circle_area(5)

6.2 模块常量 #

ruby
module Config
  DEFAULT_TIMEOUT = 30
  MAX_RETRIES = 3

  def self.timeout
    DEFAULT_TIMEOUT
  end
end

Config::DEFAULT_TIMEOUT
Config.timeout

6.3 常量查找路径 #

ruby
module A
  CONST = "A"
  
  module B
    CONST = "B"
    
    class C
      CONST = "C"
      
      def self.show
        puts CONST
        puts B::CONST
        puts A::CONST
      end
    end
  end
end

A::B::C.show

七、闭包作用域 #

7.1 捕获外部变量 #

ruby
def create_counter
  count = 0
  -> { count += 1 }
end

counter = create_counter
counter.call
counter.call
counter.call

7.2 共享变量 #

ruby
def create_pair
  value = 0
  [
    -> { value += 1 },
    -> { value -= 1 },
    -> { value }
  ]
end

inc, dec, get = create_pair
inc.call
inc.call
get.call

7.3 作用域穿透 #

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

八、作用域最佳实践 #

8.1 避免全局变量 #

ruby
$counter = 0

class Counter
  def initialize
    @count = 0
  end

  def increment
    @count += 1
  end

  def count
    @count
  end
end

8.2 使用类实例变量 #

ruby
class Config
  @@settings = {}

  def self.settings
    @settings ||= {}
  end
end

8.3 限制变量作用域 #

ruby
def process(data)
  result = transform(data)
  save(result)
  result
end

def transform(data)
  data.map(&:upcase)
end

def save(data)
  File.write("output.txt", data.join("\n"))
end

九、总结 #

本章我们学习了:

  1. 局部变量:方法/块作用域、作用域门
  2. 实例变量:对象作用域、默认值
  3. 类变量:类作用域、继承问题
  4. 全局变量:全局访问、预定义变量
  5. 常量:类常量、模块常量、查找路径
  6. 闭包:捕获变量、作用域穿透

接下来让我们学习Ruby的面向对象!

最后更新:2026-03-27