動態定義方法

使用 Ruby,你可以在執行時修改程式的結構。一種方法是使用方法 method_missing 動態定義方法。

假設我們希望能夠使用語法 777.is_greater_than_123? 測試數字是否大於其他數字。

# open Numeric class
class Numeric
  # override `method_missing`
  def method_missing(method_name,*args)
    # test if the method_name matches the syntax we want
    if method_name.to_s.match /^is_greater_than_(\d+)\?$/
      # capture the number in the method_name
      the_other_number = $1.to_i
      # return whether the number is greater than the other number or not
      self > the_other_number
    else
      # if the method_name doesn't match what we want, let the previous definition of `method_missing` handle it
      super
    end
  end
end

使用 method_missing 時要記住的一件重要事情是,還應該覆蓋 respond_to? 方法:

class Numeric
   def respond_to?(method_name, include_all = false) 
     method_name.to_s.match(/^is_greater_than_(\d+)\?$/) || super
   end
end

忘記這樣做會導致一個不一致的情況,當你可以成功呼叫 600.is_greater_than_123,但 600.respond_to(:is_greater_than_123) 返回 false。