こんにちは、浅野です。
前回のブログ更新からあっという間に3ヶ月が経ちました。
本当に早いです。
前回は、Ruby Silverを受験するぞ!という記事を書きました。
前回の記事
気になる結果ですが…
無事に合格できました!!
そして、勢いそのままRuby Goldも受験し、
こちらも合格することができました!わーい!
とは言ったものの、
特にGoldの試験は難しく、参考書に載ってない問題も多く出題され、
非常に焦りました。
試験中は、PCに頭突きしたい衝動に苛まれ、
最後の採点ボタンを押す手は震えました。
無事合格できたものの、自分の知識不足を改めて痛感し、
この結果に甘んじてはいけないなーと思っています。
というわけで今回は、
試験で間違えたことで、新しく得た知識のアウトプットをしていきたいと思います。
今回取り上げるのは、Moduleクラスのインスタンスメソッド、append_featuresです。
恥ずかしながら試験を受けるまで、きちんと理解していませんでした。
早速、以下の2つのコードを見ていきましょう。
A
module M
def self.append_features(klass)
super
p klass.ancestors
end
end
class C
include M
end
B
module M
def self.append_features(klass)
p klass.ancestors
end
end
class C
include M
end
上記のコードでは、append_featuresというメソッドを上書いたmodule Mが、
class Cにincludeされています。
違いとしては、append_features内のsuperの有無です。
それぞれどのような挙動になるかを見ていきたいと思います。
そもそもappend_featuresとはどのようなメソッドでしょうか。
公式リファレンスによると、
Module#include の実体
とあります。
つまり、appned_featuresを上書くことで、
includeされる際の挙動に影響が出ることになります。
superがあれば、既存のappend_featuresが継承され、
モジュールがincludeされますが、
ない場合は、includeされません。
実際にirbで挙動を確認していましょう。
まずAのコードです。
こちらはsuperを記述しています。
出力結果は以下となりました。
[C, M, Object, Kernel, BasicObject]
一方、superを記述していないBはというと、
[C, Object, Kernel, BasicObject]
module Mがincludeされていません。
ということで、append_featuresを上書く際は、
superを記述しないと、モジュールがincludeされなくなってしまいます。
これによって想定と挙動が異なる可能性が生まれるので、
注意が必要ですね。
Ruby Goldではこんな知識が問われます。
普段滅多に見ないメソッドが出題され、
私は結構焦ってしまいましたが、
新しい知識を習得できたので良かったです。
試験範囲としてあまり知られていないところであるかと思いますので、
どなたかのお役に立てば幸いです。

