From b69f3eb1e1a8ec86890bb1dacc859f4efa0e1edd Mon Sep 17 00:00:00 2001 From: Kazuhiro NISHIYAMA Date: Wed, 22 Jul 2026 13:55:19 +0900 Subject: [PATCH] =?UTF-8?q?=E6=A4=9C=E7=B4=A2=E3=82=AF=E3=82=A8=E3=83=AA?= =?UTF-8?q?=E3=81=A7=20=3F.=20=E8=A8=98=E6=B3=95=E3=81=AE=E3=83=A2?= =?UTF-8?q?=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E9=96=A2=E6=95=B0=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E5=8F=97=E3=81=91=E4=BB=98=E3=81=91=E3=82=8B?= =?UTF-8?q?(=E3=82=B5=E3=83=BC=E3=83=90=E3=83=BC=E6=A4=9C=E7=B4=A2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rurema/bitclust#250 のフォローアップ(#277 の PR body に記録した件)。 クエリ入力は表示と違い版に紐付かないため、動的 /search(SimpleSearcher)で .# / ?. の両記法を常に受理する。 parse_method_spec_pattern の逆転文字列正規表現は "#."/",." と同じ選択肢に "?" を含んでいなかったため、"Kernel?.open" は "?" がクラス名側に付いて 0 件になっていた。"?" を追加し、tr で従来どおり正準形 .# に正規化する。 Kernel.#open・Kernel#open・Kernel.open・Kernel::open・裸の ?.open の 挙動は回帰テストで確認済み。 静的検索(search_ranker.js)側は Aliki テーマからの verbatim vendor 方針の ため本 PR では変更しない。調査の過程で、静的検索では修飾付き検索 (File.open や Kernel.#open など。モジュール関数に限らない)がクエリの 一律 "."→"::" 書き換えとインデックスの full_name 形式の不一致により 従来から 0 件になることが判明しており、vendored 方針下での対応方針も 含めて別 issue で扱う。 refs #250 Co-Authored-By: Claude Fable 5 --- lib/bitclust/simplesearcher.rb | 12 ++++++++++-- test/test_simplesearcher.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/bitclust/simplesearcher.rb b/lib/bitclust/simplesearcher.rb index 2584ef73..4e6fb5d1 100644 --- a/lib/bitclust/simplesearcher.rb +++ b/lib/bitclust/simplesearcher.rb @@ -73,10 +73,18 @@ def parse_method_spec_pattern(pat) end return pat, nil, nil if /\A[A-Z]\w*\z/ =~ pat return nil, '$', $1 if /\$(\S*)/ =~ pat - _m, _t, _c = pat.reverse.split(/(::|[\#,]\.|\.[\#,]|[\#\.\,])/, 2) + # bitclust#250: "?." is an alternate spelling of the module-function + # separator ".#" (Ruby >=4.0 docs display it that way since #277; see + # NameUtils.display_typemark). Accept it here regardless of which + # Ruby version the query is about -- this is query *input*, not + # display, so both notations are always accepted. "?" is added to the + # same reversed-pattern alternative that already matches "#." and ",." + # (a marker character immediately followed by ".", read in the + # reversed pattern), so "?." matches the same way "#." already does. + _m, _t, _c = pat.reverse.split(/(::|[\#,]\.|\.[\#,\?]|[\#\.\,])/, 2) _m || raise c = _c.reverse if _c - t = _t.tr(',', '#').sub(/\#\./, '.#') if _t + t = _t.tr(',?', '##').sub(/\#\./, '.#') if _t m = _m.reverse return c, t, m end diff --git a/test/test_simplesearcher.rb b/test/test_simplesearcher.rb index 2a097cfb..59586e8f 100644 --- a/test/test_simplesearcher.rb +++ b/test/test_simplesearcher.rb @@ -15,6 +15,12 @@ def setup == Class Methods --- bar = reopen Kernel +== Module Functions +--- open + +== Instance Methods +--- puts + == Special Variables --- $spespe @@ -45,4 +51,26 @@ def test_simple_search assert_equal([], search_pattern(@db, " "), 'space') assert_equal([], search_pattern(@db, ""), 'blank') end + + # bitclust#250 follow-up: the dynamic server's /search accepts free-text + # queries, and a module function may be typed in either notation -- + # "Kernel.#open" (bitclust's own internal spec-string form, still what + # docs for Ruby < 4.0 display) or "Kernel?.open" (what docs for Ruby >= + # 4.0 display since #277). Both must resolve to the same method, + # regardless of which notation the *query* uses -- the query parser has + # no idea (and shouldn't need to know) which doc version the user is + # thinking of. + def test_module_function_query_notation + [['Kernel?.open', 'open'], # new (>=4.0 display) notation + ['Kernel.#open', 'open'], # existing (bitclust-internal) notation: regression check + ['?.open', 'open'], # bare module-function marker, no class name + ['Kernel#puts', 'puts'], # instance method: unaffected by the "?." change + ].each{|q, expected| + ret = search_pattern(@db, q) + assert_not_equal([], ret, q) + assert_equal(expected, ret[0].name, q) + } + # Singleton-method dot notation ('Hoge.h' => 'hoge' in test_simple_search + # above) is also unaffected; kept there rather than duplicated here. + end end