ZetCode

Ruby self 关键字

最后修改日期:2025 年 4 月 27 日

本教程讲解如何使用 Ruby 的 self 关键字。self 关键字是 Ruby 面向对象特性的基础。

self 关键字引用当前对象,即方法调用的默认接收者。它会根据在代码中的使用位置改变上下文。

理解 self 对于编写惯用的 Ruby 代码至关重要。它影响方法定义、类方法和实例变量访问。

实例方法中的基本 self

在实例方法中,self 引用类的实例。此示例展示了如何使用 self 访问实例变量。

basic_instance.rb
class Person
  def initialize(name)
    @name = name
  end
  
  def introduce
    puts "Hello, my name is #{self.name}"
  end
  
  def name
    @name
  end
end

person = Person.new("Alice")
person.introduce

这里的 self.name 调用当前实例的 name getter 方法。self 关键字明确了我们正在调用一个方法。

类方法中的 self

在类方法定义中,self 引用类本身。这是 Ruby 定义类级别方法的方式。

class_methods.rb
class Logger
  def self.info(message)
    puts "[INFO] #{message}"
  end
  
  def self.error(message)
    puts "[ERROR] #{message}"
  end
end

Logger.info("Application started")
Logger.error("Something went wrong")

self. 前缀在类本身上定义方法,而不是在实例上。这些方法直接在类上调用。

用于方法链式调用的 self

从方法中返回 self 可以实现方法链式调用。这创建了一个流畅的接口,可以按顺序调用方法。

method_chaining.rb
class Calculator
  def initialize(value = 0)
    @value = value
  end
  
  def add(num)
    @value += num
    self
  end
  
  def subtract(num)
    @value -= num
    self
  end
  
  def result
    @value
  end
end

calc = Calculator.new
puts calc.add(5).subtract(2).add(10).result

每个方法都返回 self,从而可以链式调用。最后的 result 调用返回计算出的值。

模块定义中的 self

在模块内部,self 引用模块本身。这用于定义模块级别的方法和常量。

module_self.rb
module MathUtils
  def self.square(x)
    x * x
  end
  
  def self.cube(x)
    x * x * x
  end
end

puts MathUtils.square(5)
puts MathUtils.cube(3)

使用 self 定义的模块方法直接在模块上调用。它们不需要将模块混入类中。

用于显式接收者的 self

使用 self 作为显式接收者可以使方法调用更清晰,并区分局部变量和方法调用。

explicit_receiver.rb
class BankAccount
  attr_accessor :balance
  
  def initialize(balance = 0)
    @balance = balance
  end
  
  def deposit(amount)
    self.balance += amount
  end
  
  def withdraw(amount)
    self.balance -= amount
  end
end

account = BankAccount.new(100)
account.deposit(50)
account.withdraw(30)
puts account.balance

这里的 self.balance 调用 setter 方法,而单独的 balance 会引用一个局部变量。显式接收者避免了歧义。

单例方法中的 self

self 用于为单个对象定义单例方法。这些方法仅对该特定实例存在。

singleton_methods.rb
greeting = "Hello, world"

def greeting.shout
  self.upcase + "!"
end

puts greeting.shout
puts greeting.upcase

begin
  "Another string".shout
rescue => e
  puts "Error: #{e.message}"
end

shout 方法仅在 greeting 对象上可用。其他字符串没有此方法,错误显示了这一点。

类定义中的 self

在类定义内部但在方法外部,self 引用正在定义的类。这用于元编程。

class_definition.rb
class Animal
  puts "In Animal class definition, self is #{self}"
  
  def self.species
    puts "Species method called on #{self}"
  end
  
  def initialize
    puts "In instance method, self is #{self}"
  end
end

Animal.species
animal = Animal.new

输出显示了 self 如何改变上下文。在类定义内部,它是类本身;而在实例方法中,它是实例。

来源

Ruby 关键字文档

本教程通过实例方法、类方法、方法链式调用等实际示例,涵盖了 Ruby 的 self 关键字。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 Ruby 教程