Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby | カスタムオブジェクトを作成する

概要

カスタムオブジェクトを作成する

詳細

Rubyメタプログラミング機能を利用して、動的にクラス内の定義を生成します。

サンプル仕様

lambdaのリストを与えると、リストの中からランダムにlambdaを実装したメソッドを定義するクラスを作成します。

動的にクラスを作るためのメソッドはRandomMethodHoldable moduleに定義します。
RandomMethodHoldableは
lambdaのリストをClass変数に保持するappend_lambdasをクラスメソッドを持ちます。
lambdaのリストからランダムにどれかを取得しめインスタンスメソッドとして定義するための
define_some_method_from_lambdasをクラスメソッドとして持ちます。

RandomMethodHoldableを利用するサンプルとして
RandomMethodHolderクラスを定義して、RandomMethodHoldableをincludeします。
RandomMethodHoldableでappend_lambdas、define_some_method_from_lambdasを利用して
動的にメソッドを追加し、実際の動作を確認します。

サンプル

require 'active_support/concern'
require 'pp'

module RandomMethodHoldable
  extend ActiveSupport::Concern

  module ClassMethods
    def append_lambdas(*lambdas)
      instance_variable_set :@lambdas, lambdas
    end

    def define_some_method_from_lambdas(method_name)
      lambdas = @lambdas
      define_method method_name do |*args|
        lambdas.shuffle.first.call *args
      end
    end
  end
end

class RandomMethodHolder
  include RandomMethodHoldable
  # 足し算(1を足す)、掛け算(2を掛ける)、割り算(2で割る)を定義
  append_lambdas -> (x){x + 1}, -> (x){x * 2}, -> (x){x / 2}
  define_some_method_from_lambdas :method1
  define_some_method_from_lambdas :method2
  define_some_method_from_lambdas :method3
end

hoge = RandomMethodHolder.new
puts hoge.method1 4
puts hoge.method2 4
puts hoge.method3 4

※実行結果は都度変化します。
下記は、かけ算・割り算・足し算の順にメソッドが定義されたケース。

8
2
5