はじめに
メタプログラミングは、プログラムが自身を操作したり変更したりすることを指します。
この辺りは知識としてあったんですが、実装で触れる機会も特にありませんでした。
業務でmethod_missing
を使用する場面があって、「おお!これがメタプログラミングか!!」となったので、忘れないように書いていきます。
メタプログラミングとは
メタプログラミングは、プログラムが自身の振る舞いや構造を操作するプロセスらしい。
method_missing メソッドとは
method_missing
は、Rubyの特別なメソッドの一つです。
method_missing
を見た時に、「魔法やん!」って思っていたら色々な記事で魔法と言っていたので、認識は正しかったようです。
これを初見で見た時に理解できないことは私は魔法学校出身ではないことの証明でもあるので実装で詰まっていた時間も許せるなと思いました。
method_missing
はどんなメソッドかというと、オブジェクトが存在しないメソッドが呼び出された際に自動的に呼び出されます。
これを活用することで、未定義のメソッドに対する柔軟な処理が可能になります。
No method error
がない世界ですね
method_missing の使用法
- 基本的な構文
def method_missing(method_name, *args, &block) # 未定義のメソッドが呼ばれた際の処理を記述する end
method_name
は呼び出されたメソッドの名前を表し、args
は引数の配列、block
はブロックを表します。respond_to_missing?
メソッドの実装method_missing
を使う際には、対応するrespond_to_missing?
メソッドも実装することが推奨されます。 これは、オブジェクトが特定のメソッドを実装しているかどうかを判断するために用いられます。
def respond_to_missing?(method_name, include_private = false) # method_name が対応するメソッドを実装しているかを返す処理を記述する end
method_missing の活用例 動的な属性アクセス method_missing を使用する典型的な例は、動的な属性アクセスの実装です。以下のようなクラスを考えてみましょう。
class DynamicAttributes def initialize @attributes = {} end def method_missing(name, *args) if name.to_s =~ /^set_(.*)=$/ @attributes[$1] = args[0] elsif @attributes.key?(name.to_s) @attributes[name.to_s] else super end end def respond_to_missing?(name, include_private = false) name.to_s.start_with?('set_') || @attributes.key?(name.to_s) || super end end
このクラスでは、set_
で始まるメソッドが呼ばれた際に、それに対応する属性を動的に設定します。また、属性の値を取得するためのメソッドも同様に動的に生成されます。
dynamic_obj = DynamicAttributes.new dynamic_obj.set_name = "John" dynamic_obj.set_age = 30 puts dynamic_obj.name # => "John" puts dynamic_obj.age # => 30
まとめ
method_missing
は、Rubyにおける強力なメタプログラミング機能の一つです。
その適切な活用により、柔軟性の高いコードを実現することができます。しかし、過度な使用はコードの可読性や保守性を損なう恐れがあるため、慎重に使う必要があります。是非、実際の開発でmethod_missing
を活用し、Rubyのメタプログラミングの世界を探索してみてください。