ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

自分で作っておきながらすっかり忘れてしまってたのでBUGってた。

lsモジュールで"/"区切りの仮想ディレクトリがバリバリ表示されて、おおスゲーと自画自賛してたんですが。
ふと、「・・・"dir1/dir2/"のlsで、"hoge/dir1/dir2/"がヒットしたりしてないだろうな・・・」とやってみたら。

見事にヒットしちゃいました。 Σ(゚д゚lll)

lsモジュールと、HTMLプラグインのlsとnaviが対象です。例えば"dir1/dir2"で引っかけた場合、これらは

dir1/dir2
dir1/dir2_foobar
dir1/dir2/foo/bar

というふうに、"dir1/dir2"で始まるもののみを引っかけなければなりません。

hoge/dir1/dir2

こんなのが引っ掛かってしまうという事は、通常の文字列検索になってしまってるという事です。

で、実はページのタイトルのインデックスを操作するgrain_Index_Matchクラス自体には "listmatch()" という、そのものズバリのメソッドを用意してあったのです。
これ・・・0.0.2の時点では使ってたんですよ。ところが今回の大改修で検索処理が全部yb_Finder経由に置き換えられて、そしてyb_Finderにはlistmatchの機能を入れてなかったんです。ということでlistmatchの部分が全部スポイルされてしまった訳です。

ということでyb_Finderに $use_listmatch メンバを追加して、テストケースを追加して動かしてみたのですが・・・今度はMatch側で嵌った。

"dir1/dir2"でlistmatch()するのと、"dir1/dir2/"でlistmatch()するのとでは結果が異ならなければならいのですが・・・なぜか末尾を"/"にした場合、listmatch()の段階で結果が0件になる。何故だ・・・と思ってlistmatch()で使ってる正規表現を見たら。

preg_match('/^' . preg_quote($keyword, '/') . '($|\/)/mi');

こんな感じになってました!ということは末尾に"/"つきでキーワードを渡してしまうと、

/^keyword\/($|\/)/mi

という正規表現になり、"keyword//"にマッチすることになってしまいます。

・・・これ、Matchのlistmactch()を作った時点では、"dir1/dir2"も"dir1/dir2/"も同じ結果で良いだろうと考えてたんですよね。思い出しました。
しかし、これは同じじゃ駄目なのです。というのは、"dir1/dir2"でlistmatch()した場合は

dir1/dir2
dir1/dir2/foo/bar
・・・は当然として
dir1/dir2_foobar

もヒットしなければならないからです。なぜなら「"dir1/dir2"で始まるタイトル一覧」の取得という意味になるので。
一方"dir1/dir2/"の場合は、仮想ディレクトリ上の上位になる "dir1/dir2" は引っ掛からなくなりますし、当然"dir2_aaa"みたいなのもNGにならなければなりません。あくまでも、"dir1/dir2/"で始まるタイトルを引っかけなければなりません。

というわけで、grain_Index_Matchクラスまで修正する羽目に。

なんというか自分、つくづくこうした業務ロジック的な部分が弱い・・・。実際に動かし出してようやく、頭が「あーそういえばこれの場合大丈夫かなー」と思いつく始末。鬱。