😺

method_missingに触れた~メタプログラミング~

に公開

はじめに

メタプログラミングは、プログラムが自身を操作したり変更したりすることを指します。
この辺りは知識としてあったんですが、実装で触れる機会も特にありませんでした。
業務で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?メソッドも実装することが推奨されます。
    これは、オブジェクトが特定のメソッドを実装しているかどうかを判断するために用いられるみたいです。

[https://docs.ruby-lang.org/ja/latest/method/Object/i/respond_to_missing=3f.html:embed:cite]

def respond_to_missing?(method_name, include_private = false)
  # method_name が対応するメソッドを実装しているかを返す処理を記述する
end

method_missing の活用例
method_missing を使用する典型的な例は、動的な属性アクセスの実装です。
動的な続映アクセス。。。ふーんすごいジャン

class MyClass
  def method_missing(name, *args)
    puts "メソッド '#{name}' は定義されていません。引数: #{args}"
  end

  def respond_to_missing?(name, include_private = false)
    true  # 全てのメソッド呼び出しに応答する場合
  end
end

ここでhelloメソッドを呼んだときにどうなるのかを見てみましょう。
NoMethodErrorになるかな

irb(main):010:0> obj = MyClass.new
=> #<MyClass:0x00007fe8b3932c40>
irb(main):011:0> obj.hello("world")
メソッド 'hello' は定義されていません。引数: ["world"]
=> nil

ならない!!!!!素晴らしい魔法!!!!

まとめ

今回はrailsの魔法と呼ばれるメタプログラミングに触れました。
こういう記法などをちゃんと理解することで実装の方針などの考慮にちゃんと気づけると思ったので、これからも色々試していきたいですね

Discussion