Perl と Moo で、Undo・Redo・マクロを備えた簡易テキストエディタを作っていく全10回の連載です。挿入と削除だけの Editor クラスから始め、直前のテキストを1つ取っておくだけの Undo が2回目で止まるところで、操作そのものをオブジェクトにして履歴に積む方法に切り替えます。undo メソッド、Moo::Role による約束、History クラス、Redo、マクロと足していき、対話型のエディタに仕上げたあと、第10回で、作ってきたものが Command パターンだと名前を付けます。
各回は前の回のコードに手を入れていく作りなので、通して読むなら第1回からが早道です。このページは目次を兼ねた案内板です。入口は「どこから読むか」で、困りごとが決まっているなら「困りごとから探す」で、順に追うなら「全話一覧」で選んでください。
対象は、Moo の has と with でクラスとロールを書いたことがある方です。コードは Perl v5.36 以降(サブルーチンシグネチャ)で書いています。Moo が初めてなら、先に前シリーズ「Mooで覚えるオブジェクト指向プログラミング」の目次(このページの最後にリンクがあります)から読んでください。
どこから読むか
- 第1回 — Undo の仕組みを、何も無いところから順に組み立てたいなら。第2回で、素朴な Undo が破綻するのを確かめる
- 第3回 — 「操作をオブジェクトにする」とはどういうことかを知りたいなら。第4回で undo を持たせ、何度でも戻せるようにする
- 第6回 — Undo と Redo を2つのスタックで管理する形を見たいなら。前提は第4回の execute と undo の対で、redo は第7回で足す
- 第10回 — Command パターンの役割分担から入りたいなら。作ったクラスとの対応を先に見られる
困りごとから探す
Undo が1回しか効かない、何度でも戻せない
コマンドを増やすと、どこかで壊れそう
- 第5回 — 新しいコマンドで undo を書き忘れても、Undo するまで気づけない
履歴の出し入れが、メイン処理に散らばっている
- 第6回 —
pushとpopがあちこちにあって、Redo 用のスタックを足す場所がない
やり直しや、まとめての取り消しができない
部品はあるのに、エディタとして動かせない
- 第9回 — クラスをまとめて、対話的に操作できるスクリプトにしたい
作った仕組みに名前があるのか知りたい
全話一覧
- 第1回 Undo/Redo付きのエディタを、PerlとMooで一から作る。まずはinsertとdeleteだけのEditorクラス【Editorクラス】
- 第2回 直前のテキストを1つ取っておくUndoは、2回目で止まる。previous_textが破綻する理由を確かめる【履歴の必要性】
- 第3回 何度でも戻すために、テキスト全体を毎回コピーするのは重い。「何をしたか」をInsertCommandにして記録する【操作オブジェクト】
- 第4回 操作を記録しても、まだ元に戻せない。executeと対になるundoをInsertCommandとDeleteCommandに持たせる【undoメソッド】
- 第5回 undoを書き忘れたコマンドは、Undoするまで壊れていることに気づけない。Moo::Roleのrequiresで約束にする【ロール】
- 第6回 pushとpopがメイン処理に散らばって、Redoを足す場所がない。履歴の出し入れをHistoryクラスにまとめる【Historyクラス】
- 第7回 Undoで取り消した操作を、やり直せない。redo_stackから取り出してexecuteし直すredoをHistoryに足す【Redo】
- 第8回 3か所の置換を戻すのに、Undoを3回押すことになる。複数のコマンドを1つにまとめるMacroCommandを作る【マクロ】
- 第9回 部品はそろったのに、まだエディタとして触れない。i・d・u・rを受け付ける対話型のCLIエディタに仕上げる【統合】
- 第10回 操作をオブジェクトにして履歴に積む設計には、Commandという名前がある。作ったクラスを5つの役割に当てはめる【Commandパターン】
