動態細化

改進有特殊限制。

refine 只能在模組範圍內使用,但可以使用 send :refine 進行程式設計。

using 更受限制。它只能在類/模組定義中呼叫。但是,它可以接受指向模組的變數,並且可以在迴圈中呼叫。

顯示這些概念的示例:

module Patch
  def patched?; true; end
end

Patch.send(:refine, String) { include Patch }

patch_classes = [Patch]

class Patched
  patch_classes.each { |klass| using klass }
  "".patched? # => true
end

由於 using 是靜態的,如果未首先載入細化檔案,則可以發出載入順序。解決此問題的方法是將修補的類/模組定義包裝在 proc 中。例如:

module Patch
  refine String do
    def patched; true; end
  end
end

class Foo
end

# This is a proc since methods can't contain class definitions
create_patched_class = Proc.new do
  Foo.class_exec do
    class Bar
      using Patch
      def self.patched?; ''.patched == true; end
    end
  end
end
create_patched_class.call
Foo::Bar.patched? # => true

呼叫 proc 會建立補丁類 Foo::Bar。這可以延遲到所有程式碼載入完畢之後。