Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ラーメン界の Basic Object を食べに行った話

Hiroyuki Kuromiya
December 09, 2023
17

ラーメン界の Basic Object を食べに行った話

Hiroyuki Kuromiya

December 09, 2023
Tweet

Transcript

  1. Ruby の Basic Object クラス 全ての Object の生みの親 class Hoge

    end puts Hoge.superclass # => Object puts Hoge.superclass.superclass # => BasicObject puts Hoge.superclass.superclass.superclass # => nil
  2. Object クラスを継承 結果はどうなる? class Fuga < Object def initialize(target) @target

    = target end def method_missing(message, *args) @target.__send__(message, *args) end end fuga = Fuga.new(1) print fuga.eql? 1
  3. BasicObject クラスを継承 結果はどうなる? class Fuga < BasicObject def initialize(target) @target

    = target end def method_missing(message, *args) @target.__send__(message, *args) end end fuga = Fuga.new(1) print fuga.eql? 1
  4. なんでこんなことが起こるのか? Object クラスでは eql? メソッドがすでに定義されている Fuga のインスタンスと 1 が一致しているかがチェックされる BasicObject

    クラスは eql? メソッドが定義されていない method_missing が呼び出され結果的に @target 変数に入っている eql? メソ ッドが呼び出される 1 と 1 が一致しているかがチェックされる
  5. 何が嬉しいのか? いわゆるメタプログラミング的な用途に便利 基本的にはほぼすべてのクラスの親は Object と考えて差し支えありません。しかし、 ある種のクラスを定義する際には Object クラスは持っているメソッドが多すぎる場合 があります。 例えば、

    BasicObject#method_missingを利用して Proxy パターンを実装する場合には Object クラスに定義済みのメソッドはプロクシできないという問題が発生します。こ のような場合に Object ではなく BasicObject から派生して問題を解決できます。 https://docs.ruby-lang.org/ja/latest/class/BasicObject.html