LoginSignup
0
1

More than 5 years have passed since last update.

子クラスに動的にクラスメソッドを生成させる

Posted at

イメージ

module Parent
  module MethodList
    A = 1
  end

  class Hoge
    # ...
  end
end

module Child
  module MethodList
    B = 10
  end

  class Hoge < Parent::Hoge
    define_method_from_list MethodList
  end
end

Hoge.a # => 1
Hoge.b # => 10

特異クラスを利用することで解決することが出来る。

ポイントは以下。

  • クラスメソッドは特異クラスのインスタンスメソッドとして定義される
  • define_methodはインスタンスメソッドを定義する

つまり、

  • Parent::Hogeは特異クラスの特異クラスでdefine_method_from_listを定義する
    • メソッドdefine_method_from_listParent::Hogeの特異クラスのクラスメソッドになる
  • Parent::Hogeの特異クラスでdefine_method_from_listを実行する
    • Parent::Hogeの特異クラスにインスタンスメソッドが生成される
    • メソッドaParent::Hogeのクラスメソッドになる
  • Child::HogeParent::Hogeを継承し、同じく特異クラスでdefine_method_from_listを実行する

とすれば良い。

module Parent
  module MethodList
    A = 1
  end

  class Hoge
    class << self
      class << self
        def define_method_from_list(list)
          list.constants.each do |elm|
            define_method(elm.downcase) do
              list.const_get(elm)
            end
          end
        end
      end

      define_method_from_list MethodList
    end
  end
end

module Child
  module MethodList
    B = 10
  end

  class Hoge < Parent::Hoge
    class << self
      define_method_from_list MethodList
    end
  end
end

p Parent::Hoge.a # => 1
p Parent::Hoge.b # => undefined method `b' for Parent::Hoge:Class (NoMethodError)
p Child::Hoge.a  # => 1
p Child::Hoge.b  # => 10
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1