自分で作っておきながらすっかり忘れてしまってたので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クラスまで修正する羽目に。
なんというか自分、つくづくこうした業務ロジック的な部分が弱い・・・。実際に動かし出してようやく、頭が「あーそういえばこれの場合大丈夫かなー」と思いつく始末。鬱。