Ruby 中的屬性訪問器

Nurudeen Ibrahim 2023年1月30日
  1. 在 Ruby 中使用簡單類建立例項變數 full_name
  2. 在 Ruby 中使用 attr_reader 來讀取多個例項變數
  3. 在 Ruby 中使用 attr_writer 編寫多個例項變數
  4. 在 Ruby 中將 attr_readerattr_writer 組合成 attr_accessor
Ruby 中的屬性訪問器

attr_accessor 是 Ruby OOP 設計中 attr_readerattr_writer 的快捷方式。

因此,要了解 attr_accessor,你必須首先了解 attr_readerattr_writer 是如何工作的。為了說明這些是如何工作的,我們將建立一個簡單的類。

在 Ruby 中使用簡單類建立例項變數 full_name

class Employee
  def initialize(last_name, first_name)
    @full_name = "#{last_name} #{first_name}"
  end
end

employee1 = Employee.new("John", "Doe")
puts employee1.full_name

輸出:

undefined method 'full_name' for #<Employee:0x0000558c7cbc9400 @full_name="John Doe"> (NoMethodError)

上面的簡單 Employee 類有一個建構函式,它接受員工的姓氏和名字,並使用它來建立例項變數 full_name

如果我們建立這個類的一個例項並讀取 full_name,我們會收到 NoMethodError 錯誤,如上面的輸出所示。我們將需要建立另一個返回例項變數的方法。

class Employee
  def initialize(last_name, first_name)
    @full_name = "#{last_name} #{first_name}"
  end

  def full_name
    @full_name
  end
end

employee1 = Employee.new("John", "Doe")
puts employee1.full_name

輸出:

John Doe

在 Ruby 中使用 attr_reader 來讀取多個例項變數

這是否意味著如果我們有多個需要讀取的例項變數,我們將不得不為每個變數建立一個方法?

那會使我們的課不必要地長。因此,Ruby 為我們提供了 attr_reader 來實現這一點。

class Employee
  attr_reader :full_name

  def initialize(last_name, first_name)
    @full_name = "#{last_name} #{first_name}"
  end
end

employee1 = Employee.new("John", "Doe")
puts employee1.full_name

輸出:

John Doe

正如你在上面的程式碼中看到的,我們的輸出與前面的程式碼相同。attr_reader :full_name 的新增在底層新增了 full_name 方法,允許我們編寫一個簡潔的類。

假設我們還需要重置例項變數。我們可能會嘗試這樣的事情:

class Employee
  attr_reader :full_name

  def initialize(last_name, first_name)
    @full_name = "#{last_name} #{first_name}"
  end
end

employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"

輸出:

undefined method 'full_name=' for #<Employee:0x000055bc12240940 @full_name="John Doe"> (NoMethodError)

一種方法是定義一個重置例項變數的 full_name= setter 方法。

class Employee
  attr_reader :full_name

  def initialize(last_name, first_name)
    @full_name = "#{last_name} #{first_name}"
  end

  def full_name=(name)
    @full_name = name
  end
end

employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"
puts employee1.full_name

輸出:

Nicolas Daniel

在 Ruby 中使用 attr_writer 編寫多個例項變數

Ruby 並沒有像我們在這裡所做的那樣定義一個單獨的 setter 方法,而是為我們提供了可以幫助我們的 attr_writer

class Employee
  attr_reader :full_name
  attr_writer :full_name

  def initialize(last_name, first_name)
    @full_name = "#{last_name} #{first_name}"
  end
end

employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"
puts employee1.full_name

輸出:

Nicolas Daniel

正如我們在上面的輸出中所看到的,即使我們刪除了之前定義的 setter 方法,新增 attr_writer 也得到了相同的結果。

在 Ruby 中將 attr_readerattr_writer 組合成 attr_accessor

我們的最終程式碼比為每個例項變數定義 getter 和 setter 方法要好得多,但是 Ruby 仍然允許我們通過將 attr_readerattr_writer 組合到 attr_accessor 中更進一步。

class Employee
  attr_accessor :full_name

  def initialize(last_name, first_name)
    @full_name = "#{last_name} #{first_name}"
  end
end

employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"
puts employee1.full_name

輸出:

Nicolas Daniel

正如我們在上面看到的,使用 attr_accessor,我們會自動為例項變數建立一個 getter 和一個 setter。