Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 14212] ファイルの概要

このコミットは、Go言語の実験的なexp/locale/collate/tools/colcmpパッケージ内のcolcmp.goファイルに対する変更です。colcmpは、Unicode文字列の照合(Collation)に関する比較ツールであり、この変更は、照合の回帰テスト(regression test)における比較失敗時の出力に、対象となるロケール情報を追加することを目的としています。これにより、どのロケール設定で問題が発生したのかを特定しやすくなり、デバッグの効率が向上します。

コミット

commit a35f23f34e1dbbbe23ac45563ae00de8e81d55ce
Author: Marcel van Lohuizen <mpvl@golang.org>
Date:   Wed Oct 24 11:28:18 2012 +0200

    exp/locale/collate/tools/colcmp: add locale to output of regression failure.
    
    R=r
    CC=golang-dev
    https://golang.org/cl/6749058

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/a35f23f34e1dbbbe23ac45563ae00de8e81d55ce

元コミット内容

exp/locale/collate/tools/colcmp: add locale to output of regression failure.

R=r
CC=golang-dev
https://golang.org/cl/6749058

変更の背景

この変更の背景には、Go言語のexp/locale/collateパッケージが提供する照合機能のテストとデバッグの改善があります。照合は、言語や地域によって文字列のソート順が異なるため、非常に複雑なロジックを伴います。colcmpツールは、この照合ロジックが正しく機能しているかを検証するための回帰テストを実行します。

以前のcolcmpツールの出力では、比較が失敗した場合に、どのロケール(言語や地域の設定)でその失敗が発生したのかが明確ではありませんでした。これは、複数のロケールに対してテストを実行する際に、問題の根本原因を特定する上で大きな障害となります。例えば、日本語の照合ルールとドイツ語の照合ルールでは、同じ文字列でも比較結果が異なる場合があります。ロケール情報がなければ、単に「比較が間違っている」としか分からず、どのロケール設定のバグなのかを特定するために手動で調査する必要がありました。

このコミットは、失敗メッセージにロケール情報を追加することで、デバッグプロセスを効率化し、開発者が問題をより迅速に特定できるようにすることを目的としています。

前提知識の解説

Go言語

Go(Golang)は、Googleによって開発されたオープンソースのプログラミング言語です。シンプルさ、効率性、信頼性を重視して設計されており、特に並行処理に強みを持っています。システムプログラミング、Webサービス、ネットワークプログラミングなどで広く利用されています。

exp/locale/collateパッケージ

exp/locale/collateは、Go言語の実験的なパッケージであり、Unicode文字列の照合(Collation)機能を提供していました。照合とは、特定の言語や地域(ロケール)のルールに基づいて文字列を比較し、ソート順を決定するプロセスです。例えば、ドイツ語ではウムラウト(ä, ö, ü)が特定の順序で扱われたり、スペイン語では"ch"が単一の文字として扱われたりするなど、言語によってソート順が大きく異なります。

このexp(experimental)プレフィックスは、このパッケージがまだ開発段階であり、APIが安定していない可能性があることを示していました。現在では、この機能はより成熟したgolang.org/x/text/collateパッケージに移行しており、Go言語の国際化(i18n)および地域化(l10n)の標準的な一部となっています。

照合 (Collation)

照合は、テキストデータを特定の順序で並べ替えるためのルールセットです。これは単に文字コードの順序で並べるだけでなく、言語固有の規則を考慮に入れます。例えば、以下のような点が照合によって考慮されます。

  • アクセント記号の扱い: eéのどちらが先にくるか、あるいは同じと見なされるか。
  • 大文字・小文字の扱い: Aaのどちらが先にくるか、あるいは同じと見なされるか。
  • 複合文字: スペイン語のchllのように、複数の文字で構成されるが単一の文字として扱われるもの。
  • 記号や数字の扱い: テキスト中の数字が数値としてソートされるか、文字列としてソートされるか。

これらのルールはロケールによって大きく異なるため、多言語対応のアプリケーションでは正確な照合が不可欠です。

colcmpツール

colcmpは、exp/locale/collateパッケージの一部として提供されていたコマンドラインツールです。その主な目的は、異なるロケール設定における照合の比較結果を検証することでした。具体的には、特定の入力文字列ペアに対して、期待される照合結果と実際の照合結果を比較し、不一致があれば報告する回帰テストツールとして機能します。これにより、照合ロジックのバグや意図しない変更を検出することが可能になります。

技術的詳細

このコミットは、src/pkg/exp/locale/collate/tools/colcmp/colcmp.goファイル内のエラーメッセージのフォーマット文字列を変更することで、比較失敗時の出力にロケール情報を追加しています。

具体的には、以下の2つの定数文字列が変更されています。

  1. failedKeyCompare
  2. failedCompare

これらの文字列は、fmt.Printf関数で使用されるフォーマット文字列であり、比較が失敗した際にユーザーに表示されるエラーメッセージのテンプレートを定義しています。

変更前は、これらのフォーマット文字列は行番号(%d)のみをプレフィックスとして含んでいました。 例: "%d: incorrect comparison result for input:\n"

変更後は、ロケール情報(%s)と行番号(%d)の両方をプレフィックスとして含むように変更されました。 例: "%s:%d: incorrect comparison result for input:\n"

これにより、fmt.Printfを呼び出す際に、新たにロケール情報(t.Locale)を最初の引数として渡すことが可能になり、エラーメッセージの冒頭に「[ロケール名]:[行番号]:」という形式でロケールが明示されるようになりました。

この変更は、コードのロジック自体を変更するものではなく、デバッグ出力の改善に特化しています。これにより、テストの失敗がどのロケール設定に起因するものなのかを一目で把握できるようになり、問題の切り分けと解決が大幅に容易になります。

コアとなるコードの変更箇所

--- a/src/pkg/exp/locale/collate/tools/colcmp/colcmp.go
+++ b/src/pkg/exp/locale/collate/tools/colcmp/colcmp.go
@@ -399,7 +399,7 @@ var cmdRegress = &Command{\
 }\
 \n const failedKeyCompare = `\
-%d: incorrect comparison result for input:\
+%s:%d: incorrect comparison result for input:\
     a:   %q (%.4X)\
     key: %s\
     b:   %q (%.4X)\
@@ -412,7 +412,7 @@ const failedKeyCompare = `\
 `\
 \n const failedCompare = `\
-%d: incorrect comparison result for input:\
+%s:%d: incorrect comparison result for input:\
     a:   %q (%.4X)\
     b:   %q (%.4X)\
     Compare(a, b) = %d; want %d.\
@@ -453,12 +453,12 @@ func runRegress(ctxt *Context, args []string) {\
 \t\t\t\tcount++\
 \t\t\t\ta := string(ia.UTF8)\
 \t\t\t\tb := string(ib.UTF8)\
-\t\t\t\tfmt.Printf(failedKeyCompare, i-1, a, []rune(a), keyStr(ia.key), b, []rune(b), keyStr(ib.key), cmp, goldCmp, keyStr(gold.Key(ia)), keyStr(gold.Key(ib)))\
+\t\t\t\tfmt.Printf(failedKeyCompare, t.Locale, i-1, a, []rune(a), keyStr(ia.key), b, []rune(b), keyStr(ib.key), cmp, goldCmp, keyStr(gold.Key(ia)), keyStr(gold.Key(ib)))\
 \t\t\t} else if cmp := t.Col.Compare(ia, ib); cmp != goldCmp {\
 \t\t\t\tcount++\
 \t\t\t\ta := string(ia.UTF8)\
 \t\t\t\tb := string(ib.UTF8)\
-\t\t\t\tfmt.Printf(failedKeyCompare, i-1, a, []rune(a), b, []rune(b), cmp, goldCmp)\
+\t\t\t\tfmt.Printf(failedCompare, t.Locale, i-1, a, []rune(a), b, []rune(b), cmp, goldCmp)\
 \t\t\t}\
 \t\t}\
 \t\tif count > 0 {\

コアとなるコードの解説

変更は主に2つの部分に分けられます。

  1. エラーメッセージフォーマット文字列の変更:

    • const failedKeyCompareconst failedCompare の定義において、フォーマット文字列の先頭が "%d:" から "%s:%d:" に変更されました。
    • %s は文字列のプレースホルダーであり、ロケール名がここに入ります。
    • %d は整数のプレースホルダーであり、行番号(またはテストケースのインデックス)がここに入ります。
  2. fmt.Printf呼び出しの引数追加:

    • runRegress 関数内の fmt.Printf の呼び出しにおいて、変更されたフォーマット文字列に対応するために、新たに t.Locale という引数が追加されました。
    • t はテストコンテキストを表す構造体であり、その中に現在のテストが実行されているロケール情報(Localeフィールド)が含まれています。

例えば、以前のコードでは以下のように出力されていました。

123: incorrect comparison result for input:
    a:   "foo" (...)
    ...

この変更により、以下のようにロケール情報が付加されて出力されるようになります。

en-US:123: incorrect comparison result for input:
    a:   "foo" (...)
    ...

このen-USのようなロケール情報が追加されることで、開発者はテストがどのロケール設定で失敗したのかを即座に把握でき、多言語対応のアプリケーションにおける照合関連のバグ特定と修正が格段に容易になります。

関連リンク

参考にした情報源リンク