Help us understand the problem. What is going on with this article?

メタプログラミング理解の覚書

メタプログラミングとは、「プログラミングするためのプログラムを書くこと」らしい。
実務で遭遇した例としては、「任意の数の変数を作成し、その変数を利用する」場面。

[*1..3].each do |count|
  # user_1のような変数を作成し、値を「ユーザー1」と設定する
  instance_variable_set("@user_#{count}", "ユーザー#{count}")
  # evalを使って文字列をRubyプログラムとして評価させてputsする
  puts eval("@user_#{count}")
end
# 実行結果:
# ユーザー1
# ユーザー2
# ユーザー3

eval使うと、Rubocopに警告もらうので推奨されたやり方ではないのですが、こういうのがメタプログラミングというものだそうです。

もう少し実践的なメタプログラミングの概念は「オープンクラス」。
あるクラスを拡張しようと思ったら継承が必要ですが、継承せずに実行できること。
例えば、「このプロジェクトでは、足し算をするときに、足した結果にさらに1をプラスする必要がある」という要件を満たそうとする場合。

class Integer
  def plus_one(v)
    self + v + 1
  end
end

puts 1.plus_one 1
# 実行結果:
# 3

Integerクラスを継承することなく、plus_oneというメソッドを追加できました。
追加だけではなく、既にあるメソッドと同名を定義すれば上書きできます(これがモンキーパッチ)。

先程の要件を、メソッドの拡張ではなくモンキーパッチでやってみます。
def +(v)を上書きするわけです。
けれど以下の書き方だと+の定義が無限ループに陥るのでダメです。

class Integer
  def +(v)
    self + v + 1
  end
end
# 実行結果:
# `+': stack level too deep (SystemStackError)

こういう場合は、alias_methodを使用します。
alias_methodとは「メソッドに別名を定義する」というもの。

class Integer
  alias_method :plus, :+
  def +(v)
    self.plus(v).plus(1)
  end
end
puts 1 + 2 #=> 4

※この問題は、お仕事の面接の時に問題として出題されたものです。
当時はRubyを触って半年でメタプログラミング自体分かってなかったので答えられなかったのですが、最近勉強を始め、「これについて聞いていたのか!」と分かりました。
すごくすっきりした……!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした