koheitakahashiのブログ

2020.07.01にプログラマーとして生を受けた私が学んだことや、日常について徒然に書いていきます。

『メタプログラミングRuby 第2版』を読みました

はじめに

Rubyを学び始めてから1年弱になるものの、なんとなくRubyを書いている感が否めませんでした。
そして、Rubyを使っているのではなく、Rubyに使われているという状態です。

「Rubyを理解してRubyを使いこなしたい」と思い、Rubyをより理解するために本書を手に取りました。

学んだこと、感想をまとめます。

bookmeter.com

本書の章立て

本書はⅠ部とⅡ部に別れており、以下のような章立てで構成されていました。

Ⅰ部 メタプログラミングRuby

1章 頭文字M

2章 月曜日: オブジェクトモデル

3章 火曜日: メソッド

4章 水曜日: ブロック

5章 木曜日: クラス定義

6章 コードを記述するコード

7章 エピローグ

Ⅱ部 Railsにおけるメタプログラミング

8章 Rails ツアーの準備

9章 Active Record の設計

10章 Active Support の Concern モジュール

11章 alias_method_chain の定義

12章 アトリビュートメソッドの進化

章ごとの感想

1章 頭文字M

そもそもメタプログラミングとはなんなのかという、本書の導入部分でした。

メタプログラミングとは、

コードを記述するコードを記述すること

と本書では定義されていました。

この言葉を読んだときに、これがどういうことなのかということは1章を読んだ時点でピンときませんでした

しかし、後の章を読み進めていく中でなんとなく(本当になんとなく)、この言葉の意味が掴めました。

2章月曜日: オブジェクトモデル

「メタプログラミングができる人と一緒に仕事をしていく1週間」というストーリーで書かれており、ユーモラスだと思いながら読んでいました。

Rubyはオープンクラスの仕組みの説明と、それによりどのようなことが可能になっているかということがまとめられた章でした。

特に印象に残ったのはRefinementsのお話です。
Refinementsは2020.09.04から行われていた「RubyKaigi takeout」で発表をお聞きしていましたが、その時はあまり理解できませんでした。

今回、そこで聞いたお話と本章の内容を合わせてRefinementsが「どのようなものなのか」・「どのような問題があるのか」ということが理解できました。

3章火曜日: メソッド

「メソッドを動的に定義したい時はどうするのか」が主題となっていた章でした。

Object#senddefine_methodを駆使したり、method_missingをオーバーライドしたりという方法で上記の問題に対応できるということでした。

上記の方法を知ることができて、自分の中にあるRubyの世界が広がりました。

4章水曜日: ブロック

「ブロックとは何者なのか、どのように定義されるのか」「Procとlambdaの違いとは」という内容がまとめられた章でした。

普段何気なく使っていたブロックですが、「ブロックは束縛」ということを知って、ブロックへの理解が深まりました。

また、Procとlambdaについて存在は知っており、Procを使ったことがありました。 しかし、どのように使い分ければ良いのかが分からなかったため、両者の違いがまとめられており有り難かったです。

5章木曜日: クラス定義

class_evalとは」「特異メソッドとは」「エイリアスとは」という内容がまとめられた章でした。

正直なところ、この章はよく理解できませんでした。
特に「アラウンドエイリアス」というものを理解できませんでした。

この章は、今後本書を読み返したときに改めて整理して理解したいと思います。

6章コードを記述するコード

Kernel#evalを使うことで、渡したコード文字列を実行できるということがまとめられた内容でした。

一方でコード文字列を使用する際には、コードインジェクションのリスクがあるため、注意しなければならないということを理解しました。

コード文字列については、全く知らなかったため、勉強になりました。

8章~12章 Rails ツアー

Railsの設計、コードを見ていこうというお話なのですが、あまり理解できませんでした…。

読み返したときに、再度整理したいと思いました。

全体を通しての感想

メタプログラミングは賢くなるためのものではない。柔軟になるためのものである 。

上記の言葉の意味を真に理解できているかは分かりませんが、本書を読むことで自分の中のRubyの世界が広がったという感じがあります。

普段何気なく使っている「pputsprint」がなぜメソッド名だけで実行できるのか、「ブロックとは、selfとは何者なのか」ということを理解できました。

また、メタプログラミングを使った書き方を知ることで、自分のコードの幅が広がったように思います(チームでの開発ではあまり使ってはならないものだとは思いますが)。

自分が本書を読む前に目的として立てていた「Rubyをより理解する」という目的は十分に果たすことができましたが、一度読んだだけでは理解できなかったことが多いので、再度読み直したいと思いました。