メインコンテンツまでスキップ

「動かして学ぶ!Rust入門」の執筆

· 約37分
mebiusbox
enginner

Zennで公開している「Rust入門」が「動かして学ぶ!Rust入門」として書籍化されました.ここでは、書籍の執筆について色々と書くことにしました.

はじめに

大変嬉しいことにZennで公開している「Rust入門」を書籍化することになりました.「動かして学ぶ!Rust入門」という名前で 2023年4月24日発売です.

Rust入門 | ZennRust入門

動かして学ぶ!Rust入門 | Amazon動かして学ぶ!Rust入門

動かして学ぶ!Rust入門 | SE Book動かして学ぶ!Rust入門

ここでは、執筆についてやったことや思ったことなどをここにまとめておきます.

注記

出版社からは許可をもらっています.

警告

正誤表を公開しています. また、最新のサンプルコードは以下の場所はここにあります.

執筆依頼

まず、はじめに翔泳社の編集者さんから執筆依頼のメールが届きました.書籍執筆は私の1つの夢ではあったので、快諾の連絡をして打合せや構成案の提出などをして契約しました.その後、執筆期間に入ります.

実際の執筆

私のスタイルとして、最初に必要な情報をとにかく集めます.今回は Notion を使いました.また、コードなどの参考になりそうなものはプロジェクトフォルダを作成してそこにまとめていました.執筆前に構成案を作成するのですが、その構成に合わせて資料をすべて集めます.資料を集めて、「これで書ける」と感じたら執筆を開始します.これは今回の執筆よりも前からやっている方法で今回も変わりませんでした.ちなみに、今回の執筆でそう思ったタイミングは、原稿締め切り1カ月を切っていたときです.実際に原稿はギリギリ間に合ったのですが、全くこのやり方はオススメしません.とはいえ、このやり方そのものは決して悪い方法ではなく、もっと時間に余裕を持たせようというお話です.構成を考えて調べながら書くことも可能とは思いますが、それではいつ書き終わるかが全く予想できません.特に、調べながら書く場合はあるトピックに予定以上に時間がかかることがあると破綻してしまいます.ですので、最初に資料集めをした方が書きやすいと感じています.先に全て調べなくとも、ある程度は事前にすべてチェックしておいたほうがいいです.

今回の執筆では、Markdownで原稿を書き、git で管理していました.また、mdbook を使用しています.mdbook は最初から使用することを決めていました.少なくとも今は rust に関して執筆するなら mdbook がオススメです.なにより、ブラウザ上ですぐにコードを実行して確認することができるのが便利です.複雑なコードは厳しいですが、簡単なコードなら十分です.また、vscode とも相性がいいです.SUMMARY.md から各ファイルにすぐジャンプできます.

今回の執筆は Zenn で公開している「Rust入門」を加筆したものになっています.この「Rust入門」は、もともと「Rustではじめるレイトレーシング入門」から Rust の解説部分を抜き出したものです.また、「Rustではじめるレイトレーシング入門」も「レイトレーシング入門」のC++部分をRustに書き直し、また、Rustの解説を追加したものになっています.構成段階で、編集者さんとお話したときにレイトレーシングのサンプル部分を使ってもいいか確認して入れていました.今回、A5サイズの書籍ということで手元にあった書籍を調べて行数や1行に表示する文字数を調べました.それぞれ、ばらばらで統一されていなかったのが意外で印象的でした.同じ出版社でもです.なので平均値(横38文字、縦33行)を算出して「Rust入門」の記事をTeXを使ってA5サイズで出力したところ約80ページしかなりませんでした.最初は250ページぐらいを想定とのことでしたので、かなり加筆しなければならないとわかっていました.サンプルとしてレイトレを追加したとしてもです.また、ボリューム的にも250ページはちょっと薄いかなと思ったので、300~350ページを目標としました.この時に「計画書」という資料を私の方で作って具体的にどの部分をどれくらいのページ数にするか適当に決めています.この資料は依頼されたわけではなく、勝手に私が作ったものです.実際にサンプルのページ数を除けば、このときの計画通りになったとちょっと驚いています.

構成案はまず編集者さんが提示してくれますので、それをもとに作ります.私の場合、20日間の期間がありました.ギリギリまで使って考えて構成し提出しました.これも多少「節」の移動や統合はあったものの、ほぼこのときの構成通りに執筆しています.

加筆内容としては、まずコードの量を増やしました.タイトルにもある通り「動かして学ぶ」シリーズなので、コード例を多く提示しました.「Rustの文法と機能」と「アプリケーションの開発」では、それぞれ250個、225個のリスト(コード)があります.同じ「動かして学ぶ」シリーズ(今回のはNextOneシリーズということで少し違います)で「Pythonで動かして学ぶ!機械学習の教科書」という書籍があって所持しているのですが、本当に手を動かして学べる良著だったので、参考にさせてもらいました.とはいっても、Rust入門の方はコード例を多くしているのであって、別に動かす必要はないので少し違います. 次に、「アプリケーションの開発」では単語推理ゲームとレイトレーシングを書きました.単語推理ゲームはWordleとして有名ですし、レイトレーシングはこれもまた有名なコーネルボックスのプログラムになっています.レイトレーシングは既に書いてあるのでそれの調整で済みました.いくつか間違いが見つかったのでいずれPDF版にも反映させようと思います.単語推理ゲームはicedクレートを使ったサンプルです.単語推理ゲームのロジック部分は参考にしたコードはあるのですが、それはCLIなのでGUI版を作成しました.icedクレートと注目していた tauri を使うか少し迷ったのですが、tauri はRust以外にも説明しなければいけないことが多いので、Rustだけで完結するicedクレートにしました.これは、1日で書き上げました(もちろん事前に調べていたから).ただ、説明が不十分だったり、書き方が他の部分と比べて手抜きすぎて、ここは赤字が多かったです.

執筆期間は土日、平日の夜などはフルに執筆に使っていました.体調を少しでも崩していたらやばかったですね.

当初は250ページ、目標は300ページとしていましたが、最終的には440ページ近くになりました(書籍の詳細を見るともっと多いですが、それは目次や索引などが含まれています).何とかなるものだなー.赤字などでいろいろ説明不足な部分も指摘されたのですが、これ以上ページ数を増やしたくなかったので、結構省いています.見本誌を頂いて中を見たときは、意外にスカスカだなと思いました.これはコードを追加した影響だと思います.いい感じに読みやすくなっているのかもしれません.

締め切りはどれも間に合わせました.スケジュール通りに対応できたと思います.実は予定よりもスケジュールは伸びているのですが、少なくとも私が原因ではないと思っています(まあ、原稿がまずかったのかもしれません).

監査

今回は監査を付けていません.これは編集者さんに手配してもらったり、自分でお願いすることも出来るそうです.まあ、今回の件についてはお願いできる人が思いつきませんでした.

校正・検証

原稿を書き終えてから、校正やら検証が始まります.検証は原稿に書かれているプログラムや画面が正しいかどうかチェックしてくれます.これは編集者さんの方で手配してくれます.原稿をもとに組版したものが送られてくるので、検証報告を確認しながら、チェックをして赤字という形で訂正指示をします.このとき、校正記号を知らなかったので、最初は私なりに描きこんでいたのですが、ちょっと改行問題(後述)が大きかったので、もっと簡単に表せないかと思い、校正記号について調べました(校正のルールと必ず覚えておくべき校正記号一覧 | 凸版).まさに知りたかったことだったので、特に改行や字下げなど利用しました.それ以外はむしろ面倒だったので使っていません.というのも手書きならまだしもPDFでのやり取りだったので、描画ツールを使って描くにはあまりにも面倒すぎます.専用のツールがあるなら楽なんですけどね.

特に校正で大変だったのが、改行問題です.これは Markdown に関係してきます.DocusaurusやZennなどMarkdown形式でドキュメントを書いた場合、改行をどのように扱うかはそれぞれのレンダリング処理に依存します.多くはMarkdownファイルで改行してすぐに文章を書いている場合、改行が間に入りません.mdbookもそうです.しかし、原稿として提出した場合、改行はそのまま改行として処理されます.ですので、mdbookでビルドして確認したものと組版されたものとでは結構違っていました.組版されたものは想定外の改行が多く、その度に字下げ処理されてしまい、この校正指示が大変でした(だから校正記号を調べました).これが改行問題です.他の書籍でも結構無駄に改行が入っているものを見かけます.Markdownで書いているのかなと思ってしまいます.これは厄介な問題で、それなら改行しなければいいのではと思うかもしれませんが、日本語を含めた文書でgit管理する場合、行単位での比較になりがちなので、1行にまとめてしまうとわかりづらくなってしまいます.これに関しては結局のところ、Markdown側の改行を消すしかないとの結論に今はなっています.diffの問題や執筆も1行にまとめることで書きづらくなってしまいますけどね.ではどう対応したらいいかということですが、考えられる方法として執筆時は改行あり、提出時は改行なしに変換するツールを作る方法があります.フォーマッタのようなものです.

校正に関しては原稿と一緒にgitに記録して管理していました.特に必要はなかったのですが、基本1つの校正指示に1コミットという方法を使ってやっていたのですが、あまりにも多かったので、後半は少しまとめてコミットしていたこともあります.それでも、校了になるまでに、1331回コミットしていました.

プロポーショナルフォントとIosevka

今回の執筆で一番驚いたのが、コードの印字でプロポーショナルフォントが使われていることでした.最近では、コードをプロポーショナルフォントで表示されることも時々見るので、そういう傾向にあるのかなとも思っていました.ですが、個人的にはあり得ないので等幅フォントにしてもらいました.また、「Iosevka」というフォントを指定しました.Iosevkaは等幅フォントにもかかわらず文字幅が狭い、けど読みやすいとても良いフォントです.私も使っています.ライセンスもSIL Open Font Licenseで扱いやすいです.NextOneの「動かして学ぶ!」シリーズはプロポーショナルフォントが採用されているみたいです.最初お話したときは、シリーズで同じフォントにしているとのことでしたので、この本だけ等幅フォントにするのはどうなんだろうと思いましたが、そこは譲れませんでした.というのも、Rustではコンパイルエラーで具体的な位置を指定してくれるのですが、プロポーショナルフォントではずれてしまうので、困ります.他にもいくつか等幅フォントで印字されることを前提に書いている部分もありました.

また、A5サイズなので、横幅もA4と違って狭いです.Iosevkaとはいえ、やはり文字数が個人的に足りません.そこで、インデントサイズを4から2に減らす提案をしましたが、それならフォントサイズを調整するとのことでしたので、サンプルを頂いて確認し調整しました.オススメのサイズを実際に印刷して確認してみたんですが、私としては小さすぎると感じたので、少し大きいサイズにしてあります.ただ、それだとコードを文字幅に合わせる処理が多くなるのですが、もとからするつもりだったので問題ありませんでした.Iosevkaで印字された見本を見てもかなり見やすいので、これに関しては満足しています.ちょっと太字の等幅フォントよりかは、はるかに見やすいんじゃないかなと思います.

余談ですが、Iosevkaは細かいバリエーションがあってリガチャあり・なしなどがあります.特に指定しなかった私の不手際なのですが、最初リガチャありで後からリガチャなしに変えています.

対象読者

本書の冒頭にも書いてあるとおり、ある程度プログラミング言語を学んでいる人を対象としています.ですから、変数とは何かとか、関数とは何かを詳しく説明していません.これはそういったプログラミングの基本的な内容よりもRustの機能説明に重点を置いているからです.とくに所有権を中心に書いていますが、他の内容もなるべく多く入れたつもりです.ただ、A5版であることやページ数の増加のため、あまり詰め込むわけにはいきませんでした.並列処理のところなど説明が簡潔になっている部分もありますが、それはアプリケーション開発をするところで、実際に使用して理解してもらうようになっています.

また、プログラミング初学者でも読めるようにしていると書いていますが、それは理解できるかどうかは別として本書を最初から最後までやり遂げられるという意味です.もちろん、理解できることに越したことはありませんが、Rust言語はそう簡単ではありません.ですから、コード例を多く入れています.最低限のコーディングスキルとターミナル操作(この2つができる人をプログラミング初学者と想定)が出来れば動かしながら覚えることは可能だと思います.少なくとも最初から最後まで一通りこなすことで CUI, GUI, そして並列処理を使ったアプリケーション開発を体験できるはずです.あとはわからなかったところを見直したりしてみてください.各節は見直しやすいように機能ごとになるべく分けています.私も公式ドキュメントや参考書を読んで1回で理解できた訳ではありません.公式ドキュメントを読んだ後に本書を読んでもいいし、本書を読んでから公式ドキュメントや他の参考書を読んでみるとより理解しやすくなると思っていますし、そうなれば大変嬉しく思います.

本書はすでに述べているとおり Zenn で公開している「Rust入門(無料)」を加筆したものになっています.本書に興味を持たれた方は、先に Zenn の「Rust入門」を読んでから購入を検討することも可能です.

レイトレーシング

はい、「アプリケーションの開発」にレイトレーシングのサンプルがあります.まさかのRust入門にいきなり数式が沢山でてきます.ですが、そんなことは気にしない.興味があればやってみてください.

印税について

詳しい事はお話できませんが、技術書が高い理由がわかった気がします.また、発売までの作業を考えると厳しいと思いました.ただ、原稿の執筆期間だけを考えれば悪くもないと思います.初回は原稿以外の部分でも大変と感じてしまいますが、そこを乗り切ればあとは原稿の執筆期間だけと考えると、なるほどという感じ.

モチベーション

今回の執筆については、最初にも書いているある通り書籍を執筆することが夢の1つだったので、モチベが下がることはありませんでした.普段から文書を書くときにあまりモチベが下がることはありません.というのも、資料を集めて一気に書き上げるスタイルなので、書き始めてたらそのまま最後まで書き終えます.

足りない部分

基本的に本書を読むために必要なことは順番に書いてあるつもりですが、1つだけ、pinについて書けませんでした.これは非同期処理のところでコードとしてさらっと出てきて一切説明していません.他にもいくつか説明が足らないところが多いです.ただ、あまりに細かく説明してしまうとページ数が多くなってしまうので、分かってはいても追加はしませんでした.そういった部分はZennのRust入門に追加しようと思っています.

本を書くために

私なりに思うことです.もともとPDFとして技術的な解説書を書いてきました.これは本を執筆したかったからであり、その練習でもあります.なので、原稿はTeXで書き、PDFとして出力していました.そのまま印刷できるように、かつ、そのまま本としても問題ないようにです.そのような文書を20近く書いてきました.その経験を十分に活かせたと思っています.今回の執筆では Zenn の「Rust入門」が始まりではありますが、その記事は「Rustではじめるレイトレーシング入門」の一部であり、さらに「レイトレーシング入門」という文書をRustに書き直したものです.これは2018年末に書いたものなので、4年ぐらい前になります.資料を集めて、原稿を実際に書いた期間は1カ月ほどですが、それまで積み上げてきたものがあってこそだと思います.

また、初回の構成案や計画書などはかなり正確にできました.これは見積もりに関係してきます.これについては WBS(Work Breakdown Structure)の考え方が大きいです.これにより正確な見積もりが出来るようになりました.

あと、情報の整理のやり方も大事です.Notion でも Markdown でも好きなものを使えばいいと思います.書くための情報をどのように書いておくか.基本的には箇条書きになります.十分に、そして漏らさずに.

執筆環境

WindowsでVSCodeを使いました.形式は Markdown で mdbook を使っています.プロジェクトは git で管理しています. mdbookの追加機能としてmdbook-admonitionを使っています.これは注釈を入れるものです.VSCodeの拡張機能として「テキスト校正くん」を使いました.これは表記揺れ対応に使っています.他には、Windowsツールとして keyhac, espanso を使っています.それぞれテキストを処理するためのツールです.

執筆(校正)ルール

執筆するときに、最初に自分用の執筆ルールを作成しました.これは表記揺れ対応にもつながります.主に、英語と日本語の扱い、空白の入れ方などをまとめています.また、校正時にはさらに校正ルールを作成して対応しました.これも表記揺れ対応です.一部を抜粋すると次のようなものです.

  • 日本語の句点には , (全角)を使用します. , (半角)は列挙の意味になります: i32, u32, s32赤, 青, 黄.また、日本語の中点は半角の を使います.
  • ()は半角.()内の内側に空白は入れません
  • 数字は全角ではなく半角を使用.数字の前後には空白を入れません
  • 用語の英語表記について、それが英単語のみであれば前後に半角空白を入れて Rust とし、英語+日本語の場合には空白を入れません(Rust言語).これは会社名なども同じで Google またはGoogle社とします.ただし、全角 の直後には空白を入れません:たとえば、Rust では...
  • バージョンや 英単語+数字のような場合は前後に半角空白を入れます: 1.3.0, Rust 2018
  • 数式の前後に空白を入れます
  • ファイル名の前後には空白を入れます

作図

今回の作図では Google Slide を使っています.Google Slide から PDF で出力したものを渡しています.

画像

スクショ以外の画像については、ライセンスがCC0のものを選んで使用しています.といっても使っているのは2つだけです.

ツール

今回キャプションが多かったので、原稿にあるキャプションを一括で抜き出すツールを作りました.抜けなどのチェックに利用しました.

コード

原稿にある動かせるコードは、すべてすぐに確認できるようにプロジェクトを作成しています.mdbookでは動作確認はできますが、細かいビルドチェックなどができません.なので、別途作っています.これは原稿が出来たあとに作っています.

厄介なこと

Rustは定期的にアップデートしています.エディションは変わりませんでしたが、執筆時点で 1.64、発売時には 1.69 になっていました.その間にビルドは問題なかったのですが、いくつか表示されるエラーが変わったり、Rust Playground の環境が更新されていたり、Rustのビルドの設定が変わっていたりと細かい更新がありました.これはどうしようもないので、特に発売までの間はバージョンに気を付けなければなりません.書籍で採用しているバージョンがあるとはいえ、実際に手に取って読み進めるときは最新にするでしょうから.

Zenn

Zennで公開している「Rust入門」は「Rustではじめるレイトレーシング入門」の一部です.これをZennで書いた理由というのはいくつかあるのですが、その1つとして、多くの人に読んでもらえるというのがあります.これは GitHub で公開しているだけでは出来ません.Zennを利用する前はQiitaに書いていましたが、不満があってやめました.Zennの本形式で書いていますが、特に難しくありません.アウトプットは大事ですが、どこにアウトプットするかも大事です.私はDocusaurusやGitHubで文書を公開していますが、同時にZennにも公開しています.それはやはり多くの人に見てもらえるからです.とはいえ、複数のアウトプット先があると面倒です.微妙にMarkdownの書き方が違います.そこは、ZennのMarkdown形式に変換するツールを作って対応しました.これでかなり楽になっています.

GPT

これは執筆がほぼ終わった後に検証したのですが、OpenAIのAPIを使って原稿の校正チェッカを作って試しました.かなり有用だと思います.VSCodeの拡張機能「テキスト校正くん」では簡単な表記揺れなどの対応はできますが、誤字・脱字、スペルチェック、そしてなにより適切な言い回しの候補を教えてくれるので便利です.今回は利用出来ませんでしたが、執筆の機会があれば間違いなく利用すると思います.

最後に

多くの経験をさせてもらいました.また、このような執筆の機会が得られたことをとても感謝しています.至らない部分も多いかと思いますが、多くの人に読んでもらえたなら大変嬉しく思います.