サーチ…


前書き

Monkey Patchingは、Rubyのクラスを修正して拡張する方法です。基本的には、すでに定義されているクラスをRubyで変更したり、新しいメソッドを追加したり、以前に定義されたメソッドを変更したりすることができます。

備考

猿のパッチは、例えば、宝石から、既存のルビーコードの動作を変更するためによく使われます。

たとえば、 この要点を参照してください。

これは、RailsがActiveSupportで行うような既存のルビクラスを拡張するためにも使用できます。 ここにその例があります。

任意のメソッドの変更

def hello
  puts "Hello readers"
end

hello # => "Hello readers"

def hello
  puts "Hell riders"
end

hello # => "Hell riders"

既存のルビーメソッドを変更する

puts "Hello readers".reverse # => "sredaer olleH"

class String
  def reverse
    "Hell riders"
  end
end

puts "Hello readers".reverse # => "Hell riders"

パラメータでメソッドを変更する

上書きするメソッドとまったく同じコンテキストにアクセスできます。

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

  def name
    @name
  end
end

puts Boat.new("Doat").name # => "Doat"

class Boat
  def name
    "⛵ #{@name} ⛵"
  end
end

puts Boat.new("Moat").name # => "⛵ Moat ⛵"

既存のクラスを拡張する

class String
  def fancy
    "~~~{#{self}}~~~"
  end
end

puts "Dorian".fancy # => "~~~{Dorian}~~~"

洗練された安全な猿のパッチ

Ruby 2.0以降、Rubyでは洗練されたMonkey Patchingをより安全に行うことができます。基本的に、Monkey Patchedコードが要求されたときにのみ適用するように制限することができます。

まず、モジュールで洗練を作ります:

module RefiningString
  refine String do
    def reverse
      "Hell riders"
    end
  end
end

次に、どこで使用するかを決めることができます。

class AClassWithoutMP   
  def initialize(str)
    @str = str
  end
   
  def reverse
    @str.reverse
  end
end

class AClassWithMP
  using RefiningString

  def initialize(str)
    @str = str
  end
   
  def reverse
    str.reverse
  end
end

AClassWithoutMP.new("hello".reverse # => "olle"
AClassWithMP.new("hello").reverse # "Hell riders"


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow