2016-05-30 12 views
2

私は今、「メタプログラミングのRuby」を読んでいて、概念を明確にするためにいくつかのコードを同時に書いています。私はあなたが/単一のモジュールを複数回追加/前置すると、それ以上のすべてのインクルージョンは祖先の鎖の前記モジュールの場所を変更しないことを読んだことがあります。Ruby - 単一モジュール複数回と祖先階層を含む

私は期待していない方法で動作するコードを書きましたが、実際には何が起こっていますか?

module GreatGrandfather; end 

module Grandfather 
    include GreatGrandfather 
end 

module Father 
    include Grandfather 
    prepend GreatGrandfather 
end 

module Son 
    include Father 
end 

Son.ancestors # => [Son, Father, Grandfather, GreatGrandfather] 

私はSon.ancestorsを実行すると、子は父、父は祖父を含めるとGreatGrandfatherを付加し、祖先のツリーが[Son, GreatGrandfather, Father, Grandfather]に設定されますでしょう含まれることを想定しました。明らかにそれは起こらなかった。

息子が父親を含むと、それは父親モジュールを調べ始め、include Grandfatherprepend GratGrandfatherです。 GreatGrandfatherが含まれているGrandfatherに実際に入って、prepend GreatGrandfather行しか実行しません(それはすでに祖先に存在するため無視されます)。

真実、私はそれから多くの使い方を得ることはできませんが、モジュール同士がどのように正確に繋がっているかを知ることはできません。

@edit - 私はそれをもう少し試してみましたが、どちらの場合でも私の直感が正しいとは思われません。私は、それが行えると思った2つの方法、命令の後の指示、継承階層の作成についての画像を含んでいます - 画像に現れるように見えるものは、与えられた元の例に反するため、#1も#2も起こっている。私はまだRubyのデフォルトの実装がある

答えて

1

Module#prepend_feature

起こるか分からない -

変形例コード

module GreatGrandfather 
    include Grandfather 
end 

module Grandfather 
    include GreatGrandfather 
end 

module Father 
    prepend GreatGrandfather 
    include Grandfather 
end 

module Son 
    include Father 
end 

Son.ancestors # => Son, GreatGrandfather, Father, Grandfather 

enter image description here

は要約で(のみGreatGrandfatherは変更しました)定数、メソッドをオーバーレイする、このモジュールが を既にmodまたはその祖先に追加していない場合は、このモジュールのモジュール変数とがmodに追加されます。

しかし、すでにGreatGrandfatherをGrandfatherを通じてFatherに追加しています。

あなたが期待通りに動作します。この方法:

module GreatGrandfather; end 

module Grandfather 
    include GreatGrandfather 
end 

module Father 
    prepend GreatGrandfather 
    include Grandfather 
end 

module Son 
    include Father 
end 

p Son.ancestors # => [Son, GreatGrandfather, Father, Grandfather] 

更新

1.Youは次のように例を変更カント:あなたはGreatGrandfather祖父を定義するとき

module GreatGrandfather 
    include Grandfather 
end 

module Grandfather 
    include GreatGrandfather 
end 

原因であります定義されていません。

2.これは、モジュールを別のモジュールに追加するとどうなりますか。コメントは説明しています。モジュール階層の時間はどうなりますか:

module GreatGrandfather 
    # GG 
end 

module Grandfather 
    # GG 
    # G 
    include GreatGrandfather 
    # GG 
    # G -> GG 
end 

module Father 
    # GG 
    # G -> GG 
    # F 
    prepend GreatGrandfather 
    # GG 
    # G -> GG 
    # GG -> F 
    include Grandfather 
    # Don't change the position of GG in Father hierarchy, cause it is already in ancestors 
    # GG 
    # G -> GG 
    # GG -> F -> G 
end 

module Son 
    # GG 
    # G -> GG 
    # GG -> F -> G 
    # S 
    include Father 
    # GG 
    # G -> GG 
    # GG -> F -> G 
    # S -> GG -> F -> G 
end 
+0

正直言って、ありがとうございます。私はいくつかの情報インフォメーションOPを追加しました - 体重を計ることができますか? – blob

+0

Heh、私はモジュール内のコードをすぐに実行することを完全に無視しているので、実際に自分自身で考え出しました。私はそれを試してきたので、何とかユニット化された定数について不平を言いました。もし私がファイルでそれを実行すると、最初から明確な答えが得られました。ありがとうございました! – blob

関連する問題