ジョギング
日課
- (腕立て x 50 + 腹筋 x 50) x 3
奥さん
- 体調を崩した
- 疲れがたまっていたのだろう, 週末はゆっくりとして欲しい
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (22) ~
REx - Ruby Examination の問題を自分なりにアレンジした上で 1 〜 3 問くらいずつ解いていく. 正直言ってかなり難しい. 尚, irb に動作確認環境は以下の通り.
$ ruby --version ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux] $ irb --version irb 0.9.6(09/06/30)
クラスの継承
次のコードを実行するとどうなるか.
class Cls1 def initialize puts "Cls1#initialize" end end class Cls2 < Cls1 def initialize(*args) super puts "Cls2#initialize" end end Cls2.new(1,2,3,4,5)
例外 (ArgumentError) が発生する
以下, irb にて確認.
... irb(main):013:0> irb(main):014:0* Cls2.new(1,2,3,4,5) ArgumentError: wrong number of arguments (5 for 0) ...
以下, 解説より抜粋.
super
と呼び出した場合は, 現在のメソッドと同じ引数が引き継がれる- 引数を渡さずにオーバーライドしたメソッドを呼び出す際は
super()
と指定する super()
とするか, 親クラスのdef initialize
メソッドをdef initialize(*)
とすることで, 子クラスの同名メソッドの引数を無名引数として受け取ることが出来る
以下, コードの修正案.
# パターン 1 class Cls1 def initialize puts "Cls1#initialize" end end class Cls2 < Cls1 def initialize(*args) super() puts "Cls2#initialize" end end Cls2.new(1,2,3,4,5) # パターン 2 class Cls1 def initialize(*) puts "Cls1#initialize" end end class Cls2 < Cls1 def initialize(*args) super puts "Cls2#initialize" end end Cls2.new(1,2,3,4,5)
修正案を irb で確認.
# パターン 1 irb(main):001:0> class Cls1 irb(main):002:1> def initialize irb(main):003:2> puts "Cls1#initialize" irb(main):004:2> end irb(main):005:1> end => :initialize irb(main):006:0> irb(main):007:0* class Cls2 < Cls1 irb(main):008:1> def initialize(*args) irb(main):009:2> super() irb(main):010:2> puts "Cls2#initialize" irb(main):011:2> end irb(main):012:1> end => :initialize irb(main):013:0> Cls2.new(1,2,3,4,5) Cls1#initialize Cls2#initialize => #<Cls2:0x005587ff14d750> # パターン 2 irb(main):001:0> class Cls1 irb(main):002:1> def initialize(*) irb(main):003:2> puts "Cls1#initialize" irb(main):004:2> end irb(main):005:1> end => :initialize irb(main):006:0> irb(main):007:0* class Cls2 < Cls1 irb(main):008:1> def initialize(*args) irb(main):009:2> super irb(main):010:2> puts "Cls2#initialize" irb(main):011:2> end irb(main):012:1> end => :initialize irb(main):013:0> irb(main):014:0* Cls2.new(1,2,3,4,5) Cls1#initialize Cls2#initialize => #<Cls2:0x0055ef9b3d0e60>
定数参照
以下のコードを実行するとどうなるか.
class Cls1 CONST = "aaa" end module Mod CONST = "bbb" end module Mod class Cls1 CONST = "ccc" end end module Mod class ::Cls1 p CONST end end
aaa が表示される
以下, irb にて確認.
irb(main):001:0> class Cls1 irb(main):002:1> CONST = "aaa" irb(main):003:1> end => "aaa" irb(main):004:0> irb(main):005:0* module Mod irb(main):006:1> CONST = "bbb" irb(main):007:1> end => "bbb" irb(main):008:0> irb(main):009:0* module Mod irb(main):010:1> class Cls1 irb(main):011:2> CONST = "ccc" irb(main):012:2> end irb(main):013:1> end => "ccc" irb(main):014:0> irb(main):015:0* module Mod irb(main):016:1> class ::Cls1 irb(main):017:2> p CONST irb(main):018:2> end irb(main):019:1> end "aaa" => "aaa"
以下, 解説より抜粋.
- クラス名が修飾されている場合は同じ名前であっても別のクラスになるが,
::
演算子を使うことによりネストを指定することができる - モジュール
Mod
にあるクラスCls1
でメソッドの呼び出しを行う為には,M::C
と書く - 先頭に
::
をつけるとトップレベルから探索を行う - 設問では
::Cls1
となっており, トップレベルの::Cls1
を参照する為,aaa
が表示される
フムフム.