2020年4月15日水曜日

respond_to_missing とmethod_missing を使って delegate パターンを実装してみたサンプル

概要

respond_to_missingmethod_missing は簡単に言えばメソッドが定義されているか調べることができる Object クラスのメソッドです
関数がない場合には method_missing を反応させることができます

環境

  • macOS 10.15.4
  • Ruby 2.7.1p83

サンプルコード

module Bmodule
  def self.client(options = {})
    Bmodule::Bclass.new
  end

  # Delegate to BModule::Bclass
  def self.method_missing(method, *args, &block)
    puts "method_missing" # debug
    return super unless client.respond_to?(method)
    client.send(method, *args, &block)
  end

  # Delegate to BModule::Bclass
  def self.respond_to_missing?(method_name, include_private = false)
    client.respond_to?(method_name) || super
  end
end

class Bmodule::Bclass
  module Amodule
    def func1
      puts "func1"
    end
  end
end

module Bmodule
  class Bclass
    include Amodule
  end
end

bc = Bmodule::Bclass.new
bc.func1
Bmodule.func2

こんな感じで定義することで本来は Bmodule::Bclass のインスタンスメソッドとしてコールしなければならない func1Bmodule のモジュールメソッドのようにコールすることができます

少しややこしい感じはしますが使えると便利なテクニックかなと思います
特にライブラリなどを作る場合にはメソッドのコールの仕方を短縮できたりするので便利です

0 件のコメント:

コメントを投稿