Ruby技術者認定試験の勉強のため、この機会にちゃんと理解しておく。
バージョン
$ ruby --version ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21]
継承
子クラスに定数がない場合、親クラスの定数を参照できる。
class A FOO = "foo" BAR = "bar" end class B < A BAR = "bar-B" end puts A::FOO #=> foo puts A::BAR #=> bar puts B::FOO #=> foo puts B::BAR #=> bar-B
include, prepend
モジュールも継承と同様に参照できる。
継承関係で探索するため、 include
と prepend
が混ざった場合は prepend
で追加したモジュールの定数が優先される。
module M1 FOO = "foo" BAR = "bar" end module M2 FOO = "foo-M2" end class A include M1 BAR = "bar-A" end class B prepend M1 BAR = "bar-B" end class C include M1 include M2 end class D prepend M1 include M2 end puts M1::FOO #=> foo puts M1::BAR #=> bar puts A::FOO #=> foo puts A::BAR #=> bar-A puts B::FOO #=> foo puts B::BAR #=> bar-B puts C::FOO #=> foo-M2 puts D::FOO #=> foo
スコープ
継承関係よりもネスト関係の方が優先されるが、トップレベルの定数はネスト外部とは対象外になる。詳細は 変数と定数 (Ruby 3.1 リファレンスマニュアル) を参照。
CONST = "top-level" module M CONST = "M" class A CONST = "A" end class B < A puts CONST #=> M end end class M::A puts CONST #=> "A" end class M::A::C puts CONST #=> "top-level" end