ようへいの日々精進XP

よかろうもん

2018 年 06 月 06 日 (水)

ジョギング

日課

  • お休み

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)

Cls1def 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)

フムフム.