在 Ruby 中使用安全導航

Nurudeen Ibrahim 2022年5月18日
在 Ruby 中使用安全導航

Ruby 安全導航運算子 (&.) 是在 Ruby 2.3.0 中引入的。它允許你安全地連結物件上的方法,基本上是為了避免流行的 nil:NilClass 的未定義方法錯誤。

本文將簡要討論如何在 Ruby 中使用安全導航。

在 Ruby 中使用安全導航來防止未定義的方法

示例程式碼:

class Bus
  def seats
    14
  end
end

class Vehicle
  def initialize(name)
    @name = name
  end

  def category
    Bus.new if @name == "hiace"
  end
end

vehicle = Vehicle.new("camry")
number_of_seats = vehicle.category.seats
puts number_of_seats

輸出:

undefined method `seats' for nil:NilClass (NoMethodError)

如上例所示,vehicle.category.seats 爆炸並導致 undefined method 錯誤,因為 vehicle.category 已經返回 nil。為了避免這個問題,我們需要在連結另一個方法之前檢查 vehicle.category 是否成功。

下一個示例,vehicle.category && vehicle.category.seats 表示如果 vehicle.category 成功,則應評估 vehicle.category.seats,否則應停止程式碼執行並返回 nil。這很好用,但可以用 Safe Navigation Operator 編寫。

示例程式碼:

class Bus
  def seats
    14
  end
end

class Vehicle
  def initialize(name)
    @name = name
  end

  def category
    Bus.new if @name == "hiace"
  end
end

vehicle = Vehicle.new("camry")
number_of_seats = vehicle.category && vehicle.category.seats
puts number_of_seats

輸出:

nil

在最後一個示例中,我們將使用另一個更易讀、更簡潔的安全導航版本。它在我們必須在一個物件上鍊接許多方法的情況下變得很有用,例如 object1&.method1&.method2&.method3&.method4

示例程式碼:

class Bus
  def seats
    14
  end
end

class Vehicle
  def initialize(name)
    @name = name
  end

  def category
    Bus.new if @name == "hiace"
  end
end

vehicle = Vehicle.new("camry")
number_of_seats = vehicle&.category&.seats
puts number_of_seats

輸出:

nil