ようへいの日々精進XP

よかろうもん

2018 年 08 月 03 日 (金)

ジョギング

  • 香椎浜 x 2 周
  • なんか疲れが溜まっている感じで全然体が動かず...

日課

  • (腕立て x 50 + 腹筋 x 50) x 3

リモート勉強会

参加者全員がリモート参加の勉強会に参加した.

めっちゃ, 楽しかった.

今日のるびぃ ~ 先人達の知恵と教訓 (2) ~

irb に動作確認環境は以下の通り.

$ ruby --version
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux]
$ irb --version
irb 0.9.6(09/06/30)

今回は, こちらこちら を参考にさせて頂いた.

superclass と class について

irb(main):002:0> Class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
irb(main):001:0> class Cls1; end
=> nil
irb(main):002:0> Cls1.ancestors
=> [Cls1, Object, Kernel, BasicObject]
irb(main):003:0> Object.superclass
=> BasicObject
irb(main):005:0> BasicObject.superclass
=> nil
irb(main):006:0> Class.superclass
=> Module
irb(main):001:0> Object.class
=> Class
irb(main):002:0> BasicObject.class
=> Class
irb(main):003:0> Class.class
=> Class
irb(main):004:0> Module.class
=> Class
irb(main):005:0> Kernel.class
=> Module

引き続き, const_missing (1)

以下のコードを実行するとどのような結果となるか.

class Class
  def const_missing(id)
    puts "Class#const_missing"
  end
end

class Cls1
  def self.const_missing(id)
    puts "Cls1#const_missing"
  end
end

class Cls2 < Cls1
  def hoge
    puts "CONST_VAR: #{CONST_VAR}"
  end
  def self.const_missing(id)
    puts "Cls2#const_missing"
    id = 'hoge'
  end
end

Cls2.new.hoge

以下, 解答予想.

Cls2#const_missing
CONST_VAR: hoge

以下, irb にて確認.

irb(main):022:0> 
irb(main):023:0* Cls2.new.hoge
Cls2#const_missing
CONST_VAR: hoge
=> nil

引き続き, const_missing (2)

以下のコードを実行するとどのような結果となるか.

class Class
  def const_missing(id)
    puts "Class#const_missing"
  end
end

class Cls1
  def self.const_missing(id)
    puts "Cls1#const_missing"
    id = 'Cls1'
  end
end

class Cls2 < Cls1
  def hoge
    puts "CONST_VAR: #{CONST_VAR}"
  end
  def const_missing(id)
    puts "Cls2#const_missing"
    id = 'Cls2'
  end
end

Cls2.new.hoge

以下, 解答予想.

Cls1#const_missing
CONST_VAR: Cls1

以下, irb にて確認.

irb(main):024:0* Cls2.new.hoge
Cls1#const_missing
CONST_VAR: Cls1
=> nil

引き続き, const_missing (3)

以下のコードを実行するとどのような結果となるか.

class Class
  def const_missing(id)
    puts "Class#const_missing"
    id = 'Class'
  end
end

class Object
  def Object.const_missing(id)
    puts "Object#const_missing"
    id = 'Object'
  end
end

class Cls2
  def hoge
    puts "CONST_VAR: #{CONST_VAR}"
  end
  def const_missing(id)
    puts "Cls2#const_missing"
    id = 'Cls2'
  end
end

Cls2.new.hoge

以下, irb にて確認.

irb(main):024:0> 
irb(main):025:0* Cls2.new.hoge
Object#const_missing
CONST_VAR: Object
=> nil
irb(main):026:0> Cls2.ancestors
=> [Cls2, Object, Kernel, BasicObject]

undef

インスタンスメソッドを undef しても, クラスメソッドには影響しない.

irb(main):001:0> class Foo
irb(main):002:1>   def self.foo
irb(main):003:2>     puts 'Foo.foo'
irb(main):004:2>   end
irb(main):005:1>   def foo
irb(main):006:2>     puts 'Foo#foo'
irb(main):007:2>   end
irb(main):008:1>   
irb(main):009:1*   undef foo
irb(main):010:1> end
=> nil
irb(main):011:0> 
irb(main):012:0* Foo.foo
Foo.foo
=> nil
irb(main):013:0> Foo.new.foo
NoMethodError: undefined method `foo' for #<Foo:0x00562a77f6c258>
...

private なメソッドを継承した場合の挙動

irb(main):018:0> class Foo
irb(main):019:1>   private
irb(main):020:1>   def foo
irb(main):021:2>     puts 'Private Foo'
irb(main):022:2>   end
irb(main):023:1> end
=> :foo
irb(main):024:0> class Bar < Foo
irb(main):025:1> end
=> nil
irb(main):026:0> Bar.new.foo
NoMethodError: private method `foo' called for #<Bar:0x00562a77d4e4d0>

継承したインスタンスメソッドを直接呼び出した場合には, レシーバ付きで呼び出すことは出来ない. NoMethodError となる.

irb(main):001:0> class Foo
irb(main):002:1>   private
irb(main):003:1>   def foo
irb(main):004:2>     puts 'Private Foo'
irb(main):005:2>   end
irb(main):006:1> end
=> :foo
irb(main):007:0> 
irb(main):008:0* class Bar < Foo
irb(main):009:1>   def foo
irb(main):010:2>     super
irb(main):011:2>   end
irb(main):012:1> end
=> :foo
irb(main):013:0> 
irb(main):014:0* Bar.new.foo
Private Foo
=> nil

super を利用することで, 親クラスの private メソッドを呼び出すことが出来る.

フムフム.