簡體   English   中英

元編程Ruby:在class_eval中定義inheritance

[英]Metaprogramming Ruby: defining inheritance in class_eval

我想使用 class_eval 擴展一些 class 的功能。 我想強制 class 從其他一些 class 繼承一些方法。

IE:

SomeClass.class_eval do
  # force inheritence from some other class
end

實現它的最佳方法是什么?

如果在這里覆蓋現有功能是一項硬性要求,則您需要在包含的模塊中定義這些現有方法。

class SomeClass
  include DefaultBehaviour
end

module DefaultBehaviour
  def run
    puts "ran default"
  end
end

module AlternateBehaviour
  def run
    puts "ran alternate"
  end
end

SomeClass.class_eval {
  include AlternateBehaviour
}

SomeClass.new.run #=> "ran alternate"

這是因為 ruby 的方法查找路徑。

它以 SomeClass -> Object 開頭。

當您包含 AlternateBehaviour 時,它變成 SomeClass -> AlternateBehaviour -> Object。因此直接在 SomeClass 上定義的方法仍然優先。

但是,如果這些方法是在 DefaultBehaviour 上定義的,查找路徑將變為 SomeClass -> AlternateBehaviour -> DefaultBehaviour -> Object,因此你的替代方法優先。 最近包含的模塊具有最高優先級。

在您無法控制原始 class 的情況下,您可以改為:

module AlternateBehaviour
  def self.included(base)
    base.send(:remove_method, :run)
  end

  def run
    puts "ran alternate"
  end
end

雖然在這一點上,人們開始懷疑你是否可以通過做

SomeClass.class_eval {
  def run
    "ran alternate"
  end
end

嘗試使用includeextend ,兩者均在此處進行了說明。 它們只適用於模塊; 不能在 Ruby 中修改/添加 class 的超類。

只有一個問題:您不能覆蓋 class 中已經存在的方法,以便在本文的第三條評論中進行解釋。

另請參閱主題以獲取更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM