Ruby特殊方法 #

一、特殊方法概述 #

Ruby提供了许多特殊方法,用于自定义对象的行为。

二、initialize #

2.1 基本用法 #

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

person = Person.new("Ruby", 30)

2.2 默认参数 #

ruby
class Person
  def initialize(name = "Unknown", age = 0)
    @name = name
    @age = age
  end
end

Person.new
Person.new("Ruby")
Person.new("Ruby", 30)

2.3 关键字参数 #

ruby
class Person
  def initialize(name:, age: 0, city: "Beijing")
    @name = name
    @age = age
    @city = city
  end
end

Person.new(name: "Ruby")
Person.new(name: "Ruby", age: 30, city: "Shanghai")

三、to_s和inspect #

3.1 to_s #

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

  def to_s
    "Person(name: #{@name})"
  end
end

person = Person.new("Ruby")
puts person
"#{person}"

3.2 inspect #

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

  def inspect
    "#<Person name=#{@name.inspect}>"
  end
end

person = Person.new("Ruby")
p person

3.3 to_s vs inspect #

ruby
class Point
  def initialize(x, y)
    @x, @y = x, y
  end

  def to_s
    "(#{@x}, #{@y})"
  end

  def inspect
    "#<Point x=#{@x}, y=#{@y}>"
  end
end

point = Point.new(10, 20)
puts point
p point

四、比较方法 #

4.1 == 和 eql? #

ruby
class Person
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def ==(other)
    name == other.name
  end

  def eql?(other)
    self == other
  end

  def hash
    name.hash
  end
end

p1 = Person.new("Ruby")
p2 = Person.new("Ruby")
p1 == p2

4.2 <=> 和 Comparable #

ruby
class Person
  include Comparable

  attr_reader :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def <=>(other)
    age <=> other.age
  end
end

alice = Person.new("Alice", 30)
bob = Person.new("Bob", 25)

alice > bob
alice < bob
alice == bob
[alice, bob].sort

五、method_missing #

5.1 基本用法 #

ruby
class Dynamic
  def method_missing(name, *args)
    if name.to_s.start_with?("find_by_")
      attribute = name.to_s.sub("find_by_", "")
      find_by(attribute, args.first)
    else
      super
    end
  end

  def respond_to_missing?(name, include_private = false)
    name.to_s.start_with?("find_by_") || super
  end

  private

  def find_by(attribute, value)
    puts "Finding by #{attribute}: #{value}"
  end
end

obj = Dynamic.new
obj.find_by_name("Ruby")
obj.respond_to?(:find_by_name)

5.2 动态属性 #

ruby
class Flexible
  def initialize
    @attributes = {}
  end

  def method_missing(name, *args)
    if name.to_s.end_with?("=")
      @attributes[name.to_s.chomp("=").to_sym] = args.first
    elsif @attributes.key?(name)
      @attributes[name]
    else
      super
    end
  end

  def respond_to_missing?(name, include_private = false)
    @attributes.key?(name) || name.to_s.end_with?("=") || super
  end
end

obj = Flexible.new
obj.name = "Ruby"
obj.name

六、运算符重载 #

6.1 算术运算符 #

ruby
class Point
  attr_reader :x, :y

  def initialize(x, y)
    @x, @y = x, y
  end

  def +(other)
    Point.new(x + other.x, y + other.y)
  end

  def -(other)
    Point.new(x - other.x, y - other.y)
  end

  def *(scalar)
    Point.new(x * scalar, y * scalar)
  end

  def to_s
    "(#{x}, #{y})"
  end
end

p1 = Point.new(1, 2)
p2 = Point.new(3, 4)

p1 + p2
p1 - p2
p1 * 2

6.2 数组访问 #

ruby
class Matrix
  def initialize(rows)
    @rows = rows
  end

  def [](row, col)
    @rows[row][col]
  end

  def []=(row, col, value)
    @rows[row][col] = value
  end
end

matrix = Matrix.new([[1, 2], [3, 4]])
matrix[0, 1]
matrix[0, 1] = 5

七、类型转换 #

7.1 to_a、to_h、to_i等 #

ruby
class Person
  attr_reader :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def to_a
    [name, age]
  end

  def to_h
    { name: name, age: age }
  end

  def to_s
    "#{name} (#{age})"
  end
end

person = Person.new("Ruby", 30)
person.to_a
person.to_h
person.to_s

7.2 隐式转换 #

ruby
class MyString
  def initialize(str)
    @str = str
  end

  def to_str
    @str
  end
end

my_str = MyString.new("Hello")
"World: " + my_str

八、实用示例 #

8.1 Money类 #

ruby
class Money
  include Comparable

  attr_reader :amount, :currency

  def initialize(amount, currency = "USD")
    @amount = amount
    @currency = currency
  end

  def +(other)
    raise "Currency mismatch" unless currency == other.currency
    Money.new(amount + other.amount, currency)
  end

  def -(other)
    raise "Currency mismatch" unless currency == other.currency
    Money.new(amount - other.amount, currency)
  end

  def *(multiplier)
    Money.new(amount * multiplier, currency)
  end

  def <=>(other)
    raise "Currency mismatch" unless currency == other.currency
    amount <=> other.amount
  end

  def to_s
    "#{currency} #{amount}"
  end

  def inspect
    "#<Money #{to_s}>"
  end
end

m1 = Money.new(100)
m2 = Money.new(50)

m1 + m2
m1 - m2
m1 * 2
m1 > m2

8.2 路径类 #

ruby
class Path
  def initialize(parts = [])
    @parts = parts
  end

  def /(other)
    Path.new(@parts + [other.to_s])
  end

  def to_s
    "/" + @parts.join("/")
  end

  def inspect
    "#<Path #{to_s}>"
  end
end

path = Path.new
path = path / "home" / "user" / "documents"
path.to_s

九、总结 #

本章我们学习了:

  1. initialize:对象初始化
  2. to_s和inspect:字符串表示
  3. 比较方法:==、<=>、Comparable
  4. method_missing:动态方法
  5. 运算符重载:+、-、*、[]
  6. 类型转换:to_a、to_h、to_str

Ruby文档创建完成!

最后更新:2026-03-27