トップレベルのクラス、Clockモジュールのクラスなのか判断できない
irb(main):001* class Second
irb(main):002* def initialize(player, uniform_number)
irb(main):003* @player = player
irb(main):004* @uniform_number = uniform_number
irb(main):005* end
irb(main):006> end
=> :initialize
irb(main):007* module Clock
irb(main):008* class Second
irb(main):009* def initialize(digits)
irb(main):010* @digits = digits
irb(main):011* end
irb(main):012* end
irb(main):013> end
=> :initialize
irb(main):014* module Clock
irb(main):015* class Second
irb(main):016* def initialize(digits)
irb(main):017* @digits = digits
irb(main):018* @baseball_second = Second.new("Clock", 10)
irb(main):019* end
irb(main):020* end
irb(main):021> end
=> :initialize
irb(main):022> Clock::Second.new(13)
(irb):16:in `initialize': wrong number of arguments (given 2, expected 1) (ArgumentError)
::
をつけることでトップレベルのクラスを表現し区別することができる
irb(main):001* class Second
irb(main):002* def initialize(player, uniform_number)
irb(main):003* @player = player
irb(main):004* @uniform_number = uniform_number
irb(main):005* end
irb(main):006> end
=> :initialize
irb(main):007* module Clock
irb(main):008* class Second
irb(main):009* def initialize(digits)
irb(main):010* @digits = digits
irb(main):011* @baseball_second = ::Second.new("Clock", 10)
irb(main):012* end
irb(main):013* end
irb(main):014> end
=> :initialize
irb(main):017> clock_second = Second.new("Alice", 12)
=> #<Second:0x000000010c5f5ca0 @player="Alice", @uniform_number=12>
irb(main):018> clock_second = Clock::Second.new(13)
=> #<Clock::Second:0x000000010c6bd160 @baseball_second=#<Second:0x000000010c6bd0c0 @player="Clock", @uniform_number=10>, @digits=13>
定数参照の優先順位
親クラスとネストの外側のクラスで同名の定数が定義されていると
ネストの外側の定数の方を先に参照します
。つまり、定数参照時の定数の探索順序は、最初にネスト関係を外側に向かって探索し、次に継承関係を上位に向かって探索
します。
例
class Foo
CONST = 'Foo'
end
class Bar
CONST = 'Bar'
class Baz < Foo
p CONST # => "Bar" 外側の定数
# この場合、親クラスの定数は明示的に指定しなければ見えない
p Foo::CONST # => "Foo"
end
end
class Foo
CONST = 'Foo'
end
class Bar
CONST = 'Bar'
class Baz < Foo
p CONST # => "Bar" 外側の定数
# この場合、親クラスの定数は明示的に指定しなければ見えない
p Foo::CONST # => "Foo"
end
end
トップレベルの定数定義はネストの外側とはみなされません
。したがってトップレベルの定数は、継承関係を探索した結果で参照されるので優先順位は低い
と言えます。
例
class Foo
CONST = 'Foo'
end
CONST = 'Object'
class Bar < Foo
p CONST # => "Foo"
end
# 以下のように明示的にネストしていれば規則通り Object の定数
# (ネストの外側)が先に探索される
class Object
class Bar < Foo
p CONST # => "Object"
end
end
class Foo
CONST = 'Foo'
end
CONST = 'Object'
class Bar < Foo
p CONST # => "Foo"
end
# 以下のように明示的にネストしていれば規則通り Object の定数
# (ネストの外側)が先に探索される
class Object
class Bar < Foo
p CONST # => "Object"
end
end
上位のクラス(クラスの継承関係上、およびネストの関係上の上位クラス)の定数と同名の定数(下の例で CONST) に代入を行うと、
上位の定数への代入ではなく、そのクラスの定数の定義
になります。
例
class Foo
CONST = 'Foo'
end
class Bar < Foo
p CONST # => "Foo"
CONST = 'Bar' # Bar の定数 CONST を*定義*
p CONST # => "Bar" (Foo::CONST は隠蔽される)
p Foo::CONST # => "Foo" (:: 演算子で明示すれば見える)
end
感想
ネストされた外側の定数定義の方が優先的
定義するときはどこの何の変数、定数に対してを指定する