Rubyをしっかりと理解するために「パーフェクトRuby」を読んでみた

はじめに

こんにちは。
先日(といっても5月末の話なんですが)、関西Ruby会議2017に参加しました。
で、パーフェクトRubyの著者の1人であるjoker1007さんの発表の最後にパーフェクトRubyの第2版がプレゼントされるじゃんけん大会がありました。

改訂2版 パーフェクトRuby

改訂2版 パーフェクトRuby

貰えればラッキーと思い切って参加してみたところ、なんと最後まで勝ち残りました。(勝ち残れるとは思ってなかった・・・)
そこからコツコツと読み進めて先週ようやく読み終わったのでその感想とかを書いていきたいと思います。
※ちなみにこれは本の贈呈後にjoker1007さんにサインをもらってる時の写真です。(ふ、太りすぎや・・・)
f:id:sanfrecce-osaka:20170916094646j:plain

本書の構成

Part1 Ruby ~ overview

1章 Rubyの概要

Rubyのインストール方法(WindowsMacLinux)や書籍内でのコードの記述ルールなどが書かれています。

Part2 Ruby言語仕様

2章 Rubyの基礎
3章 制御構造/メソッド/組み込み関数
4章 クラスとモジュール
5章 主な組み込みクラス/モジュール

Rubyの文法やよく使う組み込みクラスやモジュールについて書かれています。
こんな書き方もあったんだという発見が結構あります。

Part3 メタプログラミング

6章 Rubyのクラスオブジェクト
7章 動的なプログラミング
8章 Procオブジェクト
9章 Methodクラス
10章 Rubyでのリフレクションプログラミング

Rubyにおける動的にソースコードを生成するメタプログラミングについて書かれています。
メタプログラミングをどう使っていくかというよりはメタプログラミングをする上でのRubyの仕様が主に書かれています。
個人的にはここが一番重かったです。

Part4 標準添付ライブラリ

11章 ライブラリ
12章 組み込みツール

開発のうえで便利なライブラリや組み込みツールについて書かれています。

Part5 実践プログラミング

13章 gemパッケージの作り方
14章 よく使われる標準外のツール
15章 コマンドラインアプリケーション開発
16章 テストコード

gemの作り方や簡単なコマンドラインアプリケーション(todoリスト)の開発の仕方、テストコードに関して書かれています。
テストコードで使われているテスティングフレームワークRSpecやMinitestではなくTest::Unitです。

学んだこと・感じたこと

gemを読めるようになりたい、開発できるようになりたいという人にオススメの1冊

本書はRubyの文法や仕様が網羅されています。
またgemの開発方法に関しても記載されています。
そのため、「Rubyの基本はわかったけどgemが読めない」とか「gemって怖い」とかいう人にはオススメの1冊です。

メタプログラミングRubyの実践的なテクニックに関しては別途他の書籍を読む必要がある

本書は主にRubyの文法や仕様をメインに扱っているため、「仕様はわかったけどどういう風に活かせばいいの?」というニーズには応えられないと感じました。
そのため「メタプログラミングRuby」や「Effective Ruby」を別途読む必要があると思います。(どっちもまだ読んでないのであくまで推測ですが・・・)
Rubyに限ると(Railsの学習を除くと)読む順番としては下記のような順番がいいのではと考えます。

  1. Ruby入門本
  2. オブジェクト指向設計実践ガイド
  3. パーフェクトRuby
  4. メタプログラミングRuby、Effective Ruby

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

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

Effective Ruby

Effective Ruby

誤字・脱字やサンプルコードが動かないというケースがたまにある

誤字・脱字やサンプルコードが書いてある通りに動かないというケースがたまにありました。
例えば383ページのコード。(他にもいくつか見つけたけどメモっていなかった・・・)

require 'webrick'
require 'webrick/httpproxy'

proxy = WEBrick::HTTPProxyServer.new(
  :BindAddress => '127.0.0.1',
  :Port => 8080,
  :ProxyContentHandler =>
    ->(req, res) {
      puts body.scan(/<title>(.*)<\/title>/im).join rescue nil
    }
)

Signal.trap('INT') do
  proxy.shutdown
end

proxy.start

書籍内ではこのプログラムを起動して別のプログラムでwww.ruby-lang.orgにアクセスを行うとターミナルに「オブジェクト指向スクリプト言語 Ruby」が出力されるとなってますが、実はうまくいきません。
レスポンスのエンコーディングgzipになっているからです。
下記のようにするとうまくいきます。

require 'webrick'
require 'webrick/httpproxy'
require 'zlib'

def gzip_response?(res)
  res['content-encoding'] == 'gzip'
end

def open_gzip_response(res)
  Zlib::GzipReader.wrap(StringIO.new(res.body)) { |gz| gz.read }
end

proxy = WEBrick::HTTPProxyServer.new(
  :BindAddress => '127.0.0.1',
  :Port => 8080,
  :ProxyContentHandler =>
    ->(req, res) {
      body = gzip_response?(res) ? open_gzip_response(res) : res.body

      puts body.scan(/<title>(.*)<\/title>/im).join rescue nil
    }
)

Signal.trap('INT') do
  proxy.shutdown
end

proxy.start

こんな感じでうまくいかない場合があるのでサンプルコードは適宜irbなどで動かして確認してみてください。
あとjoker1007さんによると、もし間違いを見つけた場合は下記リンク先のお問い合わせフォームから報告してくださいとのことでした。
gihyo.jp

1冊読み終えるのに時間をかけすぎたらダメというのを改めて痛感した

これは本書の内容とは関係ないんですが、今回は1冊読み終えるのに時間かけすぎたというのが反省点です。
技術書は完全に理解できなくてもまずは期間を決めて一通り読んだうえで、再度わからなかったところを読み直すとかQiitaの記事書いてどんどんアウトプットするとかした方がいいのかなぁと思いました。

終わりに

パーフェクトRubyは今まで縁遠い存在であったgemやメタプログラミングが理解できるいい1冊でした。
Rubyの知識を深めたいなら読んでおいて損はないと思います。
何かご意見・ご感想あればコメントもらえるとありがたいです。