メタプログラミングRuby 第2版の読者向けの練習問題集やってみた

メタプログラミングRuby 第2版」はRubyをより深く使いこなすための素晴らしい本ですが、理解を深めるには実際にコードを書いてみることが不可欠です。読者向けの練習問題集がGitHub - kinoppyd/reading-metaprogramming-rubyに公開されているので、手を動かしながらメタプログラミングの理解を深めることができました。ぜひ、Rubyメタプログラミングについて理解を深めたい方は練習問題を試してみてください!

メタプログラミングRuby 第2版とは

メタプログラミングRuby 第2版」は、Rubyプログラミング言語メタプログラミングについて深く掘り下げた書籍です。2015年10月と少し古い本になりますが、Rubyのスキルを高めていくには必読の本になると思います。

メタプログラミングとは、プログラム自身がプログラムの構造を読んだり、変更したり、新たなコードを動的に作成したりする能力を指します。Rubyはその言語設計からメタプログラミングが容易に行える特徴を持っており、この本はその強力な機能をフルに活用する方法を詳しく解説しています。

この書籍では、Rubyのオブジェクトモデル、メソッド探索、クラス定義、コードが実行されるコンテキストなど、Rubyメタプログラミングの基礎的な概念から始まり、その後、より高度なテクニックやイディオムについて学ぶことができます。

なお、この本はあくまでメタプログラミングに特化した内容であるため、Ruby自体の基本的な文法やプログラミング技術については説明されていません。そのため、読者はRubyの基本的な知識をある程度持っていることが前提となっています。

メタプログラミングRuby 第2版で学べること

メタプログラミングRuby 第2版」では、Rubyメタプログラミングのコンセプトとテクニックを深く学ぶことができます。

具体的には以下のような内容が含まれています。

  • Rubyのオブジェクトモデル: Rubyの全ての値がオブジェクトであるという原則から始まり、オブジェクトがどのように動作するか、クラスとモジュールがどのように関連しているかなどを理解します。
  • メソッド探索: Rubyがメソッドをどのように探し出し、実行するかを学びます。また、メソッド探索の過程で起こるエラーとその対処法についても学びます。method_missingなど
  • クラス定義: Rubyのクラス定義が実は実行可能なコードであり、その結果として新たなメソッドや定数が定義されるという概念を理解します。
  • 動的メソッドとクラス: Rubyが動的な言語であることを利用して、メソッドやクラスを動的に作成・変更する方法を学びます。define_methodなど
  • コードが実行されるコンテキスト: メタプログラミングにおいて重要な、selfやスコープ、インスタンス変数のVisibilityなどについて理解します。
  • ブロックとインスタンス評価: RubyのパワフルなブロックとProcオブジェクト、それらを使ったメタプログラミングテクニックを学びます。
  • フックメソッド: クラスやモジュールが定義や継承されたとき、メソッドが追加されたときなど、特定のイベントが発生したときに自動的に呼び出されるフックメソッドについて学びます。

この書籍を通じて、Rubyに対する深い理解を得ることができ、Rubyの言語設計の背後にある理念や美学を感じ取ることができるでしょう。また、メタプログラミングがふんだんに利用されたActiveRecordActiveSupportなどの実装について理解しやすくなります。

メタプロの練習問題集の reading-metaprogramming-ruby とは

GitHub - kinoppyd/reading-metaprogramming-rubyのREADMEをみると

このリポジトリは、メタプログラミングRuby 第2版を読んだ人向けの練習問題集です。本を読んだだけだとなかなか身につかないRubyメタプログラミングの知識を、手を動かして理解することを目的にしています。

と書かれており、メタプログラミングRubyの読者向けの練習問題になっています。

章ごとにディレクトリが分かれて練習問題が格納されており、テストコードをパスするようにメタプログラミングを駆使して実装を進めていきます。また、解答もあるのでどうしてもわからないという場合は参考にできます。

メタプロの練習問題集の reading-metaprogramming-ruby をやってみた感想

メタプログラミングを実際に手を動かしながら、メタプログラミングでどんなことができるかを感触をつかむことができました。

メタプログラミングを学ぶとよくありがちなのが、実際にメタプログラミングをやりたくなって仕事のコードにいれてしまい、それが負債になってしまうという失敗があります。(私もメタプログラミングRubyを読んだ後にやってしまいましたw)メタプログラミングは強力がゆえに使い所を間違うと理解が難しく保守性の悪化やバグの温床になってしまいます。そういった意味でも、練習問題を実施することで感触を掴んでいけます。

また、実際にActiveRecrodやGemのコードを読んでいると、本書で紹介されているメタプログラミングがたびたび登場します。個人的よく見るのは 動的にメソッドを定義するdefine_methodやメソッドが見つからないときの挙動を制御するmethod_missingなどはよくみます。これらのメソッドを理解しないとコードを読むことは難しいでしょう。

ちなみに、練習問題は次のような形で出題されるので気軽に試すことができます。以下の練習問題では順序性を考慮してクラス階層にどうやってモジュールを追加するのかが問われています。includeprependを使うことで解決できます。

# reading-metaprogramming-ruby/02_object_model/02_hierarchy.rb

module M1
  def name
    'M1'
  end
end

# NOTE: これより上の行は変更しないこと


# Q1.
# 次の動作をする C1 class を実装する
# - C1.ancestors.first(2) が [C1, M1] となる
# - C1.new.name が 'C1' を返す
class C1
  def name
    'C1'
  end
end

# Q2.
# 次の動作をする C2 class を実装する
# - C2.ancestors.first(2) が [M1, C2] となる
# - C2.new.name が 'M1' を返す
class C2
  def name
    'C2'
  end
end

まとめ

Rubyの高い生産性の1つはメタプログラミングに支えられていると過言ではないと思っています。実際に、Railsや各種gemではメタプログラミングが多く利用されています。理解しより適切に使いこなすために、「メタプログラミングRuby 第2版」 を読んで、手を動かすことはおすすめです!
ぜひ書籍を買って、練習問題をやってみてください!楽しいです!