【書評】🍒「プロを目指す人のためのRuby入門[改訂2版]」を第1版と読み比べる

Ruby

はじめに

はじめまして、シモカワ(@aim2bpg)と申します。

これは「フィヨルドブートキャンプ Part 2 Advent Calendar 2021」の11日目の記事です。

先週12月2日に、プロを目指す人のためのRuby入門[改訂2版](通称:チェリー本2)
が発売されました。(11月に予約して、今週12月6日にようやく届きました🙌 )

プロを目指す人のためのRuby入門[改訂2版] 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plus)
プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plus)

この本は、フィヨルドブートキャンプのRuby中級のプラクティスで必須書籍にもなっており、輪読会でも大切に読ませていただいている一冊です。そこで、日頃からお世話になっているチェリー本の著者の伊藤さんへの感謝の気持ちも込めて、僭越せんえつながら書評という形で記事を書かせていただきます。

ただ、書評というと重たいイメージがしますので、内容的には読書感想文みたいなノリで気楽に書いていきたいと思います〜。

なお、本記事がブログ初投稿となります。よろしくお願いいたします😊

本記事の作者について

  • フィヨルドブートキャンプ現役生、Ruby歴4ヶ月(2021年12月11日時点)
  • { aim2bpg: ‘aim to be a programmer!’ }(プログラマを目指す!)
  • チェリー本1の1周目読了、輪読会で2周目に突入
  • 他言語のプログラミング経験あり(ExcelVBAでマクロを作ることができる)
  • 伊藤さんと同じ1977年生まれ

書評を書こうと思った動機

  • 買えたことに満足せず、「いつか読もう」を「今読もう」に変える。
  • 書評を書くためには、本を一通り読まないと書けないので、読む動機付けとなる。
  • 本を一通り読むことで、初心者の自分でも書評を書く素材が見えてくると思った。
  • アドベントカレンダーに投稿することで、学習のアウトプットの一つになる。
  • 伊藤さんは、きっと「ここが良かった、ここが役に立った」の声が欲しい。

以上の理由から、一石二鳥以上の価値があると考えました。

書評の方針

  • 先入観が入らないようにするために、チェリー本2に関する情報は検索しない。
  • 電子書籍版を持っていないので、紙の書籍版のチェリー本について、読んでいく。
  • 時間的制約からチェリー本1・2の改訂差分に着目して読んでいく
  • 同じく時間的制約からサンプルコードは紙面上で追えない部分のみirbで確認する。
  • 気になった点、感じた点などは、ノートに手書きで書き留めていく。

総評

シンプルに、買ってよかったと思いました。
既にチェリー本1は持っていますが、知識のアップデートのためにも手元に置いていることは大変心強い存在となりそうです。何より、あの伊藤さんと伴走してペアプログラミングしているかのような体験ができる本の最新版を持つことに、魅力を感じています。

具体的に良かったと思う理由は以下の通りです。

  • 本の内容の一言一句まで見直しされていて、書かれていることにきちんと責任を持たれている印象を受けた。
  • 少なく見ても300箇所以上の加筆・見直しを確認し、見直しがない項が珍しいほどで第1版からさらに洗練された印象を受けた。500ページ超の規模で数百箇所の分量を加筆・見直してチェックされるのは相当なご苦労があったのではないかと思う。これだけ、手塩にかけて出版されたものなら買って損はないと思った。
  • 随所に今後のバージョンについてのWebでのフォローに言及されており、買ってしばらく経って古くなったから使えないやぁ〜ということはまずなさそう。
  • サンプルコードもリファクタリングされており、別メソッドの方が短く書けたり、シンプルな例に差し替えてあったり、分かりやすいコメントを付加されるなどの読者への配慮が読み取れた。

今回、チェリー本1・2を読み比べることで、なぜ、伊藤さんが多くの方から信頼を集め、尊敬されているかの裏付けを垣間見れた気がしました。

書評の内容

説明が分かりやすくなったところ

  • P.62 第2章コラム「== true や== falseは冗長なので書かない」
  • P.82 第2章コラム「メソッド呼び出しでカッコを付ける/付けないの使い分け」
    上記2つは慣習と思っていたことを、コラムに加筆して具現化されていて分かりやすくなっています。
  • P.113 4.4.4項「sum」
    inject/reduceからsumにメソッドが置き換えてあり、こんな使い方があるなんて。
  • P.123 4.6.2項「to_hexメソッドをリファクタリングする」
    4.4.4項と同様に例題もsumに置き換えることで、ブロックパラメータが2個から1個に減ってコードがスッキリ。
  • P.152 4.9.1項「終端や始端を持たない範囲オブジェクト」
    Ruby2.6以降の範囲式で「beginless range」と「endless range」について加筆してあって分かりやすかったです。
  • P.202 第5章コラム「よく使われるイディオム(2)||=を使った自己代入(nilガード)」
    第1版の記載で理解していたのですが、第2版の記載の方がたしかに分かりやすくなっていると感じました。
  • P.367 9.2.1項「発生した例外を補足しない場合」
    サンプルコードが、6行→1行とシンプルになっていました。これは理解の助けとなってありがたい。
  • P.486 12.3.6項「SystemStackError」
    スタックが溢れたときに発生する現象が加筆されていて、すごく分かりやすくなっていました。
  • P.532 13.11項「「Railsの中のRuby」と「素のRuby」の違い」
    第1版では付録に入っていましたが、独立した節に変更されており、Railsを学習した後だからかもしれませんが、分かりやすい章立てになったと感じました。

図解で分かりやすくなったところ

  • P.170 5.2節「ハッシュ」図5−1 ハッシュの{}とブロックの{}の見分け方
  • P.345 8.6.2項「名前空間でグループやカテゴリを分ける」
    図8−8 「名前空間やクラス」と「ファイルパス」との対応
  • P.408 10.2.1項「yieldを使ってブロックの処理を呼び出す」
    図10−1 yieldを使ってブロックの処理を呼び出すときの実行フロー

親切なところ

伊藤さんの記事や書籍で驚くのは、疑問やつまづきポイントをたくさんアウトプットされていて、どれも共感するものばかりです。本当に人の痛みや気持ちがよく分かる方なんだなぁ〜としみじみ思います。

  • 各章の表紙や章・節・項の数字のデザインが一新され、識別しやすくなっています。
  • 表紙にRuby3.0対応(その後のバージョンもWebでフォロー)とあり、この先のアフターフォローも期待できます。
  • P.8 1.4.1項「macOS/Linuxの場合」
    プロンプト記号の$への言及が加筆してあって、ターミナル初心者にやさしい。
  • P.13 1.6項「Rubyを動かしてみる」
    irbで終了できない時の対処法(ctrl+C)が初学者にやさしい。
  • 主要な記事へのリンクにQRコードも追加され、スマホで手軽に見れてありがたい。
  • P19 1.9節「この章のまとめ」
    公式リファレンスの読み方について、無料のWeb bookを公開されている。
  • P.20 第1章コラム「最後まで読み切るコツ」
    インデックス読書法の紹介があり、読者への配慮を感じました。
  • P.79 2.12.7項「requireとrequire_relative」
    第1版でrequireを使って自作のRubyプログラムを読み込んでいたことに対して、読者へのお詫びがしてあり、責任感の強さを感じました。
  • P.218 6.3.5項「正規表現と組み合わせると便利なStringクラスのメソッド」
    gsubの使い方が第2引数からブロック(公式リファレンス推奨の書き方)に変わった点を丁寧に説明されていた。ここは、つい最近、輪読会でやったばかりでしたので、記憶に新しかったです。
  • 難しくなる第7章、第8章で、しんどくなったときはインデックス読書法に切り替えてもOKという感じで気にかけているくださるところに、読者の気持ちに寄り添っているなぁと感じた。
  • P406 10.1.1項「WordSynthの実装コード」
    第1版では、injectメソッドを使ってあったのですが、章の冒頭で本筋ではない内容がきて、injectメソッドってなんだっけ?とならないように、eachメソッドに置き換えられている点に配慮を感じました。且つ、injectメソッドを使ったリファクタリングに関しては、コラムの方でしっかり補足されていて、さすがだと思いました。
  • 8章の例題が「deep_freezeメソッド」から「rainbowメソッド」に差し替え。
    初学者にとって、黒いターミナル画面にカラフルな文字が並ぶ光景はちょっとした感動もので、遊び心ある素敵な題材だと思いました。書籍では白黒だからとQRコードでスマホから見れるようにしている心配りもさすがだと思いました。
  • P.490 12.4.4項「デバッガ(debug.gem)を使う」
    先取り感があって楽しかったです。第1版で説明のあったbyebugについても、伊藤さんの記事で補足がしてあるので読者も自由に選択できます。
  • 全体的に現場でこう書く、これは書かない(使わない)の伊藤さんの経験論が、読者目線で大変親切。
  • 第11章で比較的新しい機能のパターンマッチについて、しっかりとした解説があり、この先注目の機能になりそうですので、いざコードを書いたり見たりした時は、チェリー本2に戻ってこようと思います。

参考になったところ

以下は、第2版で加筆されたもののみです。

  • P.71 第2章コラム「「!で終わるメソッドは破壊的メソッドである」は間違い」
    たしかに勘違いしていましたので、参考になりました〜。
  • P.195 5.6.10項「…を使った引数の委譲」
    バージョンによって引数の渡し方が変わるので、気を付けたいと思いました。
  • P.165 第4章コラム「エイリアスメソッドがたくさんあるのはなぜ?」
    前々から疑問に思っていたことを具現化されていて大変参考になりました。これは初学者にも優しい!
  • P.428 第10章コラム「メソッドチェーンを使ってコードを書く」
    メソッドチェーンで改行できるのが参考になりました。デバッグ方法も紹介されていて親切ですね。
  • P.511 13.6節「非推奨機能を使ったときに警告を出力する」
    バージョン依存があるとのことで、気を付けたいと思いました。
  • P.536 13.11.4項「Rubyの構文や言語機能がまったく別の用途で使われているケースがある」
    Railsを使うようになると、たしかに〜と思うような内容でした。

分かりにくかったところ

第6章までで、2つありました。 ※そもそも難しい第7章のクラス以降は除外。
ここで、同じ疑問を持たれた方に向けて、不慣れながらも解説に挑戦してみます。

  • P.31 2.3.2項「文字列の比較」bytesメソッド
    「あ」は1文字なのに、バイト値の配列の要素が3つで返ってくるのはなぜか?
# 引用元:
# https://github.com/JunichiIto/ruby-book-codes-v2/
#           blob/main/sample-codes/chapter_02/code_02_03_02.rb
# bytesメソッドを使うと文字列のバイト値が配列で返る(配列は第4章で詳しく説明します)
'a'.bytes   #=> [97]
'b'.bytes   #=> [98]
'A'.bytes   #=> [65]
'abc'.bytes #=> [97, 98, 99]
'あ'.bytes  #=> [227, 129, 130]

UTF-8における平仮名は3バイト(16進数)で表現されます。つまり、平仮名の’あ’は、16進数で「E3 81 82」になります。これをbytesメソッドでは10進数で返すそうなので、16進数の「E3 81 82」は、10進数では「227 129 130」となります。これを配列の要素3つで返しているというわけです。
Qiitaの参考記事では、この仕様を踏まえて16進数に変換する方法を紹介してありました。
(フィヨルドブートキャンプ卒業生のima1zumiさんの記事です。ありがとうございます🙏 )
参考:(Ruby)文字列を16進数に変換する – Qiita
   UTF8 3byte (e3)

  • P.158 4.10.7項「再帰呼び出し」階乗の計算
    factorialメソッドの引数 n = 5 の時に、戻り値が 120 になるのは分かります。
    しかし、引数 n = 0 の時に、戻り値が 1 になるのはなぜでしょうか?
# 引用元:
# https://github.com/JunichiIto/ruby-book-codes-v2/
#           blob/main/sample-codes/chapter_04/code_04_10_07.rb
def factorial(n)
  # 再帰呼び出しを使わずに階乗を計算する例
  ret = 1
  (1..n).each { |n| ret *= n } # (コメント加筆) n = 0の時はeachメソッドが実行されない
  ret
end
factorial(5) #=> 120
factorial(0) #=> 1

n = 0 の時は、(1..n)のRangeオブジェクトが、(1..0)の範囲となります。調べてみると、Rangeオブジェクトの範囲演算子において、最初の値が最後の値を超えている場合は、(1..0).each { … } の行は1度も実行されず、最初にretに代入した1がそのまま、factorialメソッドの戻り値となるわけです。
参考:Rubyの範囲演算子は降順のイテレートには使えない – $ cat /var/log/shin

さいごに

  • 今回の書評を通して自分も将来、伊藤さんみたいにたくさんの方々から喜ばれるようなプロダクトを何か作ってみたいなぁ〜と思いました🤔
  • いつもお世話になっているフィヨルドブートキャンプ関係者の皆様、Part 1 の方で同じ11日目に記事を投稿されているparuさん、Ruby本輪読会メンバーの皆様、いつもありがとうございます!
    今後ともどうかお付き合いのほど、よろしくお願いいたします🙏
  • 改訂2版で表紙のチェリーが2つになっているということは、次の改訂3版ではチェリーが3つ?そもそも3つのチェリーはあるの?と調べてみたら…ありました😳(「さくらんぼ 3つ子」で検索)。ちょっと気が早いですが、もし、今後更なる改訂がありましたら改訂3版も楽しみにしております😁

明日は、sasaboさんです😄 お楽しみに!!

参考

用語の見直し

複数回登場する用語をほんの一部抜粋してもこれだけの見直しがかけられています。
別に前のままでもいいじゃんと思ってしまいそうですが、Rubyでは「名前重要」という考え方があって、おそらく、伊藤さんが文中で違和感を持たれたり、より分かりやすい名前をと思って見直された結果ではないかと推測しました。

  • 公式ドキュメント→公式リファレンス
  • ブロック引数→ブロックパラメータ(配列は引数のまま)
  • コーディングルール→コーディング規約
  • Mac→macOS
  • メソッドの戻り値を返す→メソッドの戻り値を返却
  • 初期値→デフォルト値
  • ユニーク→一意
  • 範疇→スコープ
  • ネスト→入れ子

古くなった記載も見直されており、読者に違和感を持たれないよう配慮してありました。

  • 第7章クラスの例題の阪急宝塚駅 梅田→十三じゅうそう 間の運賃:150円→160円
  • サンプルコードの西暦(元号):2016年(平成28年)→2021年(令和3年)

要所で用語の定義を加筆していただいて、こういう配慮もありがたいなと感じました。

  • ショートサーキット
  • セグフォ
  • テストファースト
  • パース など

正誤表へのフィードバック

  • 問い合わせ→正誤表に掲載済み
    P.124 4.6.3「to_intsメソッドを作成する」のサンプルコードのinject→sum
  • 問い合わせ中(2021年12月11日時点) 正誤表に掲載済み(2021.12.14更新)
    P.386 9.4.6「例外処理も手を抜かずテストする」の例題処理→例外処理

あわせて読みたい

プログラミング経験がない方が、いきなりチェリー本で学習しようとすると挫折してしまう可能性があります。そういう方には「ゼロからわかる Ruby 超入門」で学習されてからチェリー本へのステップアップをおすすめします。フィヨルドブートキャンプのRuby初級のプラクティスでも必須書籍となっており、今でも分からないことがあると読み返している信頼の一冊です。

ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)
ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)
タイトルとURLをコピーしました