#Ruby超入門 の設計方法

画像1

Ruby超入門著者の五十嵐です。Ruby超入門は、プログラミングが初めての人へ向けたRubyプログラミングの入門書です。

この記事は結城浩さんのこのtweetがきっかけで書き始めました。


『こういう「メイキング話」はまとめて欲しさあります。映画の「設定資料集」みたいに。レア感があるのと、背後の苦労と楽しみが見え隠れして個人的な親しみがわく。』

Ruby超入門を書くにあたり、たくさんの本を読みました。結城さんの本では「数学文章作法基礎編・推敲編」と「Java言語プログラミングレッスン」を良く読みました。

数学文章作法基礎編の第1章の冒頭にこんな文があります。

『順序を意識すること。特に「ここまで読み進めてきた読者は何をしているか」という観点で順序を意識することが極めて重要です。』

今回の執筆はこの「順序」を延々と考えつづける日々でした。作業としてはブロックを積んで階段を作る作業と似ています。新しい知識をブロックに見立てて、どの順で積むとスムースで、段差が小さくなるのか。新知識AとBはどちらを先に説明すべきなのか。別の知識Cを途中に挟むと理解がかんたんにならないか。そんなことをずっと考えていました。

考え続けていると、ある日気づきます。「あれ、このブロック、ここで割れるのか」と。割れると新しい組み合わせが生まれます。また並び替えて考えて、また別のブロックが割れることに気づき・・・と繰り返します。

この観点で「Java言語プログラミングレッスン」や他の入門書を読むと、自分が初学者のときに読んでいた気持ちとはまったく違う景色が見えました。なぜこの概念の説明がここにあるのか、なぜこの知識はこれよりも前なのか。そうやって何冊かの本を自分の本(の設計)と比べ、自分の本を直す作業をしました。前述の本の他には「たのしいRuby」が丁寧な設計と、たくさんの知識を簡潔にまとめた文章になっていて、そのすごさを実感しました。

脱線しますが、JavaはRubyと比べて説明が必要な事柄が多く、この設計作業はさらに難しかったのだろうと思います。それは裏を返すと、Rubyが少なくても初学者レベルでは、スムースに説明できそうだという感触をつかんだことでもありました。

さきほどのブロックで階段を作る作業を、最初の第2章、第3章のところだけざっくり書いてみるとこんな感じになっています。

四則演算
- 初めてのプログラム puts 1 でオブジェクトとメソッドの初出
- メソッドは名前だけ最初から出して慣れてもらおうとしている
- 2つのオブジェクトを足すと1つのオブジェクトになること
- 足し方がオブジェクトの種類によって異なること
- 複数行のプログラムの初出

オブジェクト、変数、クラス
- オブジェクトがあって、変数っていう名札をくっつける
- オブジェクトが先、変数が後
- だから変数使わなくてもオブジェクトを使える(これ編集さんからレビューもらった記憶)
- クラスはあとでいきなり出てくるのも大変なので簡単に小出しにしてる

シーケンス
- if(分岐)
- 変数が重要に活用される例
- ifは、条件成立・不成立によって実行ルートが変わる
- 実行されない行がある概念の初出
- 条件成立・不成立はifとは独立に考えることができる(ブロックの分解)
- 大小判断、同一判断をifより前に説明
- ところで繰り返しと分岐はどちらが難しい?
- おそらく繰り返しの方がイメージが難しい
- 繰り返しはルートの一筆書きで考えられなず、実行行番号とx回目の両方を考えなくてはいけない
- 同じ行が2回以上実行される概念の初出

繰り返し
- 回数の決まった繰り返し(3.times)と回数が実行時に決まる繰り返し(array.each)
- 回数の決まった繰り返しの方が簡単なので先に出した
- 正直、3.timesというコードは日常使いではそれほど重要ではないからカットしてもよかった
- しかしこれを書くことで回数の決まった繰り返しの概念を学べる
- あわせて最も簡単なdo end(変数が無いもの)も学べる
- do endの初出(変数が無いもの)

ここからは具体的な例を見てみましょう。たとえばifの「条件成立・不成立はifとは独立に考えることができる」がブロックを割って、説明順を並び替えた箇所です。次のコードを見てください。

a = 5
if a > 0
  puts "aは0より大きい"
end

普段は if と a > 0 を一緒に考えることが多いですが、概念としては別のものです。次のように分解してそれぞれ別に説明すると、階段1段の段差を小さくすることができます。

a = 5
puts a > 0 #=> true
if true
  puts "aは0より大きい"
end

次の例です。繰り返しの3.timesは説明のための別の概念を持ち込んだ箇所です。初期の頃は、配列 [1,2,3] の各要素で繰り返すというプログラムを最初に説明しようと検討していました。日頃よく行う操作だからです。プログラムを書くとこうなります。

array = [1,2,3]
array.each do |x|
  puts x
end

このプログラムにはいくつかの概念が混ざっています。まず、繰り返しの回数が配列の要素数によって変わります。これを説明するより前に、回数が書かれている繰り返しを先に説明したいところです。そして次の点の方が重要なのですが、do end中の変数 |x| という書き方が出てきます。このxに配列の要素1,2,3が順に代入されるのですが、これはとても難しい概念です。できればdo endの概念とは別に説明したいです。(ところでこのdo endをRubyではブロックと呼びます。この記事の「説明の塊」もブロックと名付けてしまいすみません・・・。)

そこで、先に3.timesの説明をすると、この2つを叶えることができます。

3.times do
  puts "カフェラテ"
end

このプログラムでは繰り返しの回数は3回と書かれていて分かりやすく、しかもdo end中に変数の記述もありません。繰り返しの概念を説明するときに、ほかの概念が邪魔することがなくなります。

このようにブロックを積み、並び替え、分解し、また並び替えを繰り返していると、最初のうちは明らかに良い選択が簡単にできます。思いついたときに「これは良い」と感じるようなものです。しかし段々とどちらが良いかが分からなくなってきます。

迷った例はメソッドの引数と戻り値の説明順です。処理順で考えると「引数を渡して、戻してもらう」なので「引数が先、戻り値が後」となります。しかし、引数は省略して渡さないこともできますが、戻り値は必ず何かが戻ってくると考えると、最小構成で説明していくには「戻り値が先、引数が後」となります。ここは両方のパターンを書き、前後の流れも考えた結果、「戻り値が先、引数が後」にしました。レビューで「逆順の方が自然かも?」という指摘もあったので、どちらが良かったのかの自信を持った答えはまだありません。終盤になると順序を入れ替えた方が良さそうかどうかの判断は事前につかなくなってきて、両方書いて評価するしかないという状況になっていました。

今回の執筆で学んだことは、説明順序の構成が読み易い文章をつくるということでした。説明順序、適切な例の設定、図表イラストによる視覚的な解説、主にこれらが読み易い文章になるかどうかを分ける大きなポイントではないかと考えています。

宣伝

この記事では説明順序に焦点を絞って書きましたが、図表とイラストに関する記事もこちらに書いています。

また、ぷぽさんのブログが私の気持ちをこれでもかを読み取って代弁してくれていますので、こちらもよかったら読んでみてください。機会があればこちらへのアンサーソングも書いてみたいです。

また、共著の machu さん、becoさんの執筆環境記事など、本の情報はこちらにまとめています。

「ゼロからわかる Ruby超入門」は物理書籍版と電子書籍版があります。

技術評論社サイト

Amazon

BOOTH(物理本、整数オブジェクトさん缶バッジ付き)


この記事が気に入ったらサポートをしてみませんか?