KiSAKU
技術系約5分で読めます

1語足すために、6か所を直した

公開

用語集に13語を足しました。作業そのものは半日で終わりましたが、1語につき触った場所は6か所ありました。

数が見えたので、書いておきます。

この記事で扱うこと

1つの情報が2か所に分かれていると、追加のたびに何が起きるかという話です。なぜ分けたのか、分けたことで何を手で守る必要が出たのか、そして食い違ったときに何も起きないまま壊れる箇所を書きます。

用語集は2か所に分かれている

このサイトの用語集は、解説の本文をCMSの固定ページに置いています。分野ごとに1ページ、いまは8ページあります。文章なので、コードを触らずに直せるほうが都合がよいからです。

いっぽうで、用語の一覧と検索はコード側に持っています。語・読み・1行の説明・置き場所の4つだけを並べた配列です。

export type GlossaryTerm = {
  t: string;  // 用語
  r: string;  // 読み(検索で使う)
  s: string;  // 1行の説明
  c: string;  // 分野
  id: string; // そのページ内の位置
};

なぜ一覧まで本文から作らないのか。検索のために129語ぶんの本文を毎回取りに行くのは重すぎるからです。本文は全部で9万字近くありますが、この4つだけなら十数キロバイトに収まります。読み込んだ時点で手元にあるので、入力した瞬間に絞り込めます。

1語足すと、6か所になる

分担そのものは理由があって決めたものです。ただ、追加のときにやることは1か所では終わりません。

場所 足すもの
CMS:本文 見出しと解説の本体
CMS:ページ冒頭の索引 その用語へのアンカーリンク
CMS:索引の件数ラベル 「この分野の用語(14)」の数字
コード:用語の配列 語・読み・説明・分野・id の1行
コード:関連記事の対応表 id と記事スラッグの組
コード:コメント内の語数 「用語は116語あり」という説明

13語だと78か所になります。実際には分野ごとにまとめて入れたので、手数はもっと少なく済みました。それでも1語の追加が6つの独立した編集に分かれているという構造は変わりません。

食い違ったときに何が起きるか

ここが問題の中心です。どれか1つを忘れても、エラーは出ません。

忘れた場所 見え方
本文だけ足した 検索に出てこない。書いたのに誰も辿り着けない
配列だけ足した 検索には出る。押すとそのページの先頭に着く
索引リンクを忘れた ページの中からは見つけられない
件数ラベルを忘れた 数だけが合わない。誰も気づかない
2つめが特に分かりにくい

存在しないアンカーを指すリンクは、404になりません。ブラウザは黙ってページの先頭を表示します。

検索結果から押して、用語集のページが開く。一見うまくいっているように見えます。探していた語が見つからないのは、読む人の側からは「自分の見落とし」に見えます。

並び順という、どこにも書かれていない決まり

作業していて気づいたことがあります。用語の並びは読みの順ですが、並べ替える処理はコードのどこにもありません。手で並べた順のまま出しています。

そして、その「読みの順」がどういう規則なのかも、どこにも書かれていません。既存の並びから読み取る必要がありました。

並び 読み取れること
ひらがなの語 → カタカナの語 文字コードの順に並んでいる
エスピーエフ → エーレコード 長音符は「ス」より後ろ
ティーエルエス → テキストレコード 小さい「ィ」は「キ」より前

つまり、日本語としての五十音順ではなく読みの文字列をそのまま比べた順でした。13語を正しい位置に入れるには、この規則を先に確定させる必要がありました。

ここも、間違えてもエラーは出ません。順番が少しおかしいだけです。誰も気づかないまま、少しずつ崩れていく種類の決まりです。

送ったものと、保存されたものを突き合わせた

CMSの本文は、既存の1万字ほどの中に新しい塊を差し込む形になります。差し込む処理を間違えて、もともとあった文章を壊していないかが心配でした。

そこで、送る前の文字列と、保存された後に取り直した文字列で、長さと簡単なハッシュを比べました。

// 送った内容
{"sent": "12685:c5ada48b"}
// 保存された内容を取り直したもの
{"back": "12685:c5ada48b"}

見た目の確認だけでは、1文字消えたことに気づけません。数字が一致するかどうかなら、見落としようがありません。6ページぶん、すべて一致しました。

確認の形を、目で見るものから数字に変えた

「ページを開いて、おかしくないことを確かめる」は、おかしい場所を知っているときにしか働きません。

どこが壊れたか分からない状態で使えるのは、壊れていないことが1つの値で言える方法だけです。

直し方は3つあって、まだどれも選んでいない

案 得るもの / 手放すもの
本文もコードに移す 置き場所が1つになる / 文章を直すたびにデプロイが必要になる
索引を本文から自動で作る 手作業が消える / 検索のために本文を全部読む必要が戻る
食い違いを検知する仕組みを置く 分担は変えずに済む / 検知できるのは、検知すると決めたものだけ

今回は、どれも入れずに手で6か所直しました。13語という数では、まだ仕組みを作るより手で直すほうが速いという判断です。

ただ、この判断は数が増えれば逆転します。次に足すときには、少なくとも3つめ——配列のidが本文に実在するかを確かめるだけの確認を先に用意するつもりです。並び順が規則どおりかも、同じ場所で見られます。

今回の学び

まず、置き場所を分ける判断には、必ず「同時に直す」という宿題が付いてくるということ。分けた理由は正しくても、宿題のほうは残ります。分けるかどうかを決めるときに、その宿題の重さまで数えておく必要がありました。

次に、エラーが出ない不整合がいちばん残ること。存在しないアンカーは404になりません。件数が1つずれても誰も止めてくれません。止まらない種類の間違いは、止まる間違いより長く生き残ります。

そして、コードに書かれていない決まりは、既存のものから読み取るしかないこと。並び順の規則は、どこにも書いていないのに確かに存在していました。読み取れたのは既存の116語が揃っていたからで、もし途中で1つ崩れていたら、崩れたほうを正解として続けていたはずです。

この記事を共有する

Xでポストはてブ
← ブログ一覧へ戻る