ジョギング
日課
- お休み
SRE 本輪読会
- つるべーさんの 10 章からの時系列データ, 時系列データベースの話, 流石, 専門に勉強されていて面白かった
- 松浦さんの 15 章のポストモーテムの話, 実践的な内容の話が聞けてとても良かった
帰りに久米さんと一緒の電車になって色々と話をさせてもらって刺激になった. 人って, 環境によって大きく成長するんだなと痛感した.
今日のるびぃ ~ REx - Ruby Examination にチャレンジ (20) ~
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)
クラスの継承関係
以下のコードを実行するとどうなるか.
val = 0 class Cls1 end class Cls2 < Cls1 end if Cls2 < BasicObject val += 100 else val += 15 end if Cls2 < Cls1 val += 100 else val += 15 end p val
200
以下, irb にて確認.
irb(main):001:0> val = 0 => 0 irb(main):002:0> irb(main):003:0* class Cls1 irb(main):004:1> end => nil irb(main):005:0> irb(main):006:0* class Cls2 < Cls1 irb(main):007:1> end => nil irb(main):008:0> irb(main):009:0* if Cls2 < BasicObject irb(main):010:1> val += 100 irb(main):011:1> else irb(main):012:1* val += 15 irb(main):013:1> end => 100 irb(main):014:0> irb(main):015:0* if Cls2 < Cls1 irb(main):016:1> val += 100 irb(main):017:1> else irb(main):018:1* val += 15 irb(main):019:1> end => 200 irb(main):020:0> irb(main):021:0* p val 200 => 200
以下, 解説より抜粋.
Module#<
はクラスの継承関係を比較することが出来る- if 文においては継承関係を比較している
if Cls2 < BasicObject # Cls2 は BasicObject の子孫である為, true となる val += 100 else val += 15 end if Cls2 < Cls1 # Cls2 は Cls1 の子孫でもある為, true となる val += 100 else val += 15 end irb(main):027:0> if Object < Cls2 # Object クラスは Cls2 の先祖である為, false となる irb(main):028:1> val += 10 irb(main):029:1> else irb(main):030:1* val += 1000 irb(main):031:1> end => 1300
以下, Module#<
及び Module#<=
について, ドキュメントより抜粋.
- self が other の子孫であるか, self と other が 同一クラスである場合, true を返す
- self が other の先祖である場合, false を返す
- 継承関係にないクラス同士の比較では nil を返す
irb(main):001:0> module Foo irb(main):002:1> end => nil irb(main):003:0> class Bar irb(main):004:1> include Foo irb(main):005:1> end => Bar irb(main):006:0> class Baz < Bar irb(main):007:1> end => nil irb(main):008:0> class Qux irb(main):009:1> end => nil irb(main):010:0> p Bar < Foo true => true irb(main):011:0> p Baz < Bar true => true irb(main):012:0> p Baz < Foo true => true irb(main):013:0> p Baz < Qux nil => nil irb(main):014:0> p Baz > Qux nil => nil irb(main):015:0> p Foo < Bar false => false irb(main):016:0> p Foo < Object.new TypeError: compared with non class/module
クラスの継承
以下のコードを実行するとどうなるか.
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)
Cls1#initialize Cls2#initialize
以下, irb による実行例.
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:0x00557d19ba4de8>
以下, 解説より抜粋.
def initialize(*)
は無名の可変長引数を表すsuper
はスーパークラスにある現在のメソッドと同じメソッドを呼びだすsuper
は引数指定なしで呼び出した場合は, 現在のメソッドと同じ引数が引き渡される- スーパークラスで引数を受け取る必要がない場合,
initialize(*)
とすることで, サブクラスで引数を意識する必要が無くなる
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)
Cls1
の def initialize(*)
を def initialize
とすると, 以下のように ArgumentError
例外が発生する.
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) ArgumentError: wrong number of arguments (5 for 0)
フムフム.