Skip to content

Instantly share code, notes, and snippets.

@shakemurasan
Last active August 7, 2016 03:18
Show Gist options
  • Save shakemurasan/4174fd3471feaa89c0dec1ce0ad8856f to your computer and use it in GitHub Desktop.
Save shakemurasan/4174fd3471feaa89c0dec1ce0ad8856f to your computer and use it in GitHub Desktop.
メタプログラミングRuby 第2版 P33 のサンプルコード+α
module M1
end
module M2
include M1
end
module M3
prepend M1
include M2
end
p M1.ancestors # [M1]
p M1.included_modules # []
p M2.ancestors # [M2, M1]
p M2.included_modules # [M1]
p M3.ancestors # [M1, M3, M2]
p M3.included_modules # [M1, M2]
@shakemurasan
Copy link
Author

M3の include M2 で、インクルード先の include M1 が無視される(2回目の継承チェーン挿入だから)、っていうメタプロ本文中の主題はわかる。

@necojackarc
Copy link

@muramurasan

うろ覚え & 一部勘ですが、

  • prepend & include はそれぞれと直前と直後に module を差し込む
  • 一度取り込んだ module は再度取り込んでも何もおきない

だった気がするので、

  1. M3 を定義
    • ancestors => [M3]
  2. prepend M1
    • ancestors => [M1, M3]
  3. include M2
    • ancestors => [M1, M3, M2]
  4. M2 の中の include M1
    • ancestors => [M1, M3, M2] // 既に M1 は取り込まれてるので変化なし

という感じじゃないでしょうか。

@yasaichi
Copy link

yasaichi commented Aug 7, 2016

@necojackarc
Copy link

こうしてみると、モジュールを読み取った瞬間に中のコードが読み取り元の文脈で走ってる感じがしますね :)

module M1
end

module M2
  include M1
end

module M3
  include M2 # 先に M2 を入れてみる
  prepend M1
end

p M3.ancestors => [M3, M2, M1]

ref: https://twitter.com/necojackarc/status/762124130124570624

@necojackarc
Copy link

@yasaichi 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment