はじめに
メタプログラミングについて、みなさん聞いたことありますか?
僕は聞いたことはあるけど、何なのか少し前までは知りませんでした。
👨「フレームワークや言語を作るためのプログラミングのこと...?」
みたいな理解でいました。
今回は自分自身の勉強も兼ねて記事にまとめさせていただきます!
メタプログラミングとは?
以下wikipediaより引用
メタプログラミング (metaprogramming) とはプログラミング技法の一種で、ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法、またその高位ロジックを定義する方法のこと。主に対象言語に埋め込まれたマクロ言語によって行われる。
少し噛み砕いていうと、コード自身を生成する(関数を新しく定義する、変数を作る)コードを書くことです。
「ロジックを生成するロジック」とも言われたりします。
これだけでは「だからどういうこと??」となると思うのでRubyで例を出していきます。
通常の関数定義から見てみましょう。
class Car
def running_sound
p 'ぶおーん'
end
end
sedan = Car.running_sound
sedan.running_sound #=> "ぶおーん"
よく見る def を使用して関数定義を行うやり方ですね。
もう一例出してみましょう。
class Car
def toyota(name)
p "toyota:" + name
end
def matsuda(name)
p "matsuda:" + name
end
def suzuki(name)
p "suzuki:" + name
end
end
car = Car.new
car.toyota("prius") #=> "toyota:prius"
上を見てどう思うでしょうか?
・ 共通化できないのか?
・ 定義している関数の役割が類似してる
・ 後から他のメーカーを追加したら新たに関数を作らないといけない
など面倒なことが多いですよね(インスタンス変数にname定義したいと思いますが、今は気にしないでください)
動的に関数定義、所謂メタプログラミング的な記述方法をしてみましょう!
class Car
%w(toyota matsuda suzuki).each do |maker|
define_method(maker) do |name|
p "#{maker}:" + name
end
end
end
car = Car.new
car.toyota("prius") #=> "toyota:prius"
上記を見るとわかる通り、メタプログラミングすることによって下記の点が改善されました。
・ 定義している関数の役割が類似している箇所は共通化。
・ 配列に要素を追加するだけでメソッドを追加
まとめ
いかがでしたでしょうか。
今回は、メタプログラミングについてコードを交えて分かりやすくまとめました。
今回の記事が多くの方に参考になったら幸いです。
参考資料