給定一個 Module Foo,我想擴展這個模塊,但不保留模塊 name Foo。
# sscce (irb)
module Foo
class Foo; end
end
module Bar
include Foo
end
> Foo::Foo
Foo::Foo
> Bar.ancestors
[Bar, Foo]
> Bar::Foo
Foo::Foo
我怎樣才能Bar::Foo在不重新定義課程的情況下成為Bar::Foo(不是Foo::Foo)?
我已經嘗試include和prepend并include Foo.clone具有相同的結果。我認為可以安全地假設它參考原始類定義,很好,但我仍然希望class Foo實際屬于Bar.
uj5u.com熱心網友回復:
也許這樣的事情可以作業?
module Foo
class Foo
def foo
puts "inside: #{self.class}"
end
end
end
module Bar
class Foo < ::Foo::Foo; end
end
現在當你這樣做時:
a = Foo::Foo.new
a.foo # inside: Foo::Foo
如果你這樣做
b = Bar::Foo.new
b.foo # inside: Bar::Foo
而不是試圖以Foo一種棘手的方式包含/擴展,只需在Bar模塊內創建一個新類并依賴繼承?
uj5u.com熱心網友回復:
你不能通過包含使一個類屬于一個模塊。甚至更多 - 即使沒有包含,類也不屬于模塊(只有對類的參考可用作模塊常量)。當您匯入Foo到 時Bar,您將常量和實體方法從帶到那里Foo,這就是為什么您可以Foo::Foo通過使用Bar::Foo常量訪問并且它指向唯一標識的類Foo::Foo。
如果你想擁有 class Bar::Foo,它將是一個由這個“地址”唯一標識的不同的類。如果你想讓它與 相同Foo::Foo,你必須included在模塊中使用鉤子Foo,然后做一些繁重的元編程作業,從舊的類創建一個新類,并將它分配給新模塊中具有相同名稱的常量.
或者,也許僅僅克隆這個類就足夠了:
module Foo
class Foo; end
def included(mod)
mod.const_set('Foo', self::Foo.clone)
end
end
module Bar
include ::Foo
end
obj1 = Foo::Foo.new
obj2 = Bar::Foo.new
Foo::Foo == Bar::Foo # false
但我不確定克隆是否足以應對所有情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/348312.html
