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

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

このコミットは、Go言語の標準ライブラリstrconvパッケージ内のテストファイルtestfp.gotestftoa.goにおける、テスト失敗報告関数の修正に関するものです。具体的には、testing.T型のメソッドであるErrorfの呼び出しがErrorに置き換えられています。

コミット

commit 64023e7b7d8ce78af2f08564dfcccca243a64a17
Author: Rob Pike <r@golang.org>
Date:   Wed Nov 19 18:43:04 2008 -0800

    a few Errorfs should have been Error
    
    R=rsc
    DELTA=6  (0 added, 0 deleted, 6 changed)
    OCL=19662
    CL=19664

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

https://github.com/golang/go/commit/64023e7b7d8ce78af2f08564dfcccca243a64a17

元コミット内容

このコミットは、Go言語の初期段階におけるtestingパッケージのAPI使用に関する修正です。コミットメッセージ「a few Errorfs should have been Error」が示す通り、テストコード内で誤ってt.Errorfが使われていた箇所をt.Errorに修正しています。

変更されたファイルは以下の2つです。

  • src/lib/strconv/testfp.go
  • src/lib/strconv/testftoa.go

これらのファイルでは、テストが失敗した場合にエラーメッセージを出力するためにt.Errorfが使用されていましたが、これがt.Errorに統一されました。

変更の背景

Go言語のtestingパッケージは、テストの実行と結果報告のための基本的な機能を提供します。testing.T型は、個々のテスト関数に渡される構造体で、テストのステータスを報告するための様々なメソッド(例: Error, Errorf, Fatal, Fatalfなど)を提供します。

このコミットが行われた2008年11月は、Go言語がまだ一般に公開される前の非常に初期の段階でした。この時期は、言語仕様や標準ライブラリのAPIが活発に設計・変更されていた過渡期にあたります。

t.Errort.Errorfはどちらもテストを失敗としてマークし、指定されたメッセージを出力しますが、そのメッセージのフォーマット方法に違いがあります。

  • t.Error(args ...interface{}): 引数をスペースで区切って出力します。fmt.Printlnのように動作します。
  • t.Errorf(format string, args ...interface{}): fmt.Printfと同様に、フォーマット文字列と引数を使ってメッセージを整形して出力します。

このコミットの背景には、おそらくtestingパッケージのAPI設計における初期の揺れや、特定の状況下でのErrorErrorfの使い分けに関する規約の確立があったと考えられます。この修正は、テストコード内でのエラー報告の一貫性を保つため、または特定のケースでErrorfのフォーマット機能が不要であると判断されたために行われた可能性があります。

前提知識の解説

Go言語のtestingパッケージ

Go言語には、標準でテストをサポートするためのtestingパッケージが用意されています。このパッケージを使用することで、ユニットテストやベンチマークテストを簡単に記述・実行できます。

  • テスト関数: func TestXxx(t *testing.T)というシグネチャを持つ関数がテスト関数として認識されます。Xxxの部分は任意の英数字の並びです。
  • *testing.T: テスト関数に渡される*testing.T型の引数は、テストの実行中にテストの状態を管理し、エラーを報告するためのメソッドを提供します。
  • エラー報告メソッド:
    • t.Error(args ...interface{}): テストを失敗としてマークし、引数をスペース区切りで出力します。テストの実行は継続されます。
    • t.Errorf(format string, args ...interface{}): テストを失敗としてマークし、fmt.Printf形式でフォーマットされたメッセージを出力します。テストの実行は継続されます。
    • t.Fail(): テストを失敗としてマークしますが、メッセージは出力しません。テストの実行は継続されます。
    • t.FailNow(): テストを失敗としてマークし、現在のテスト関数を即座に終了させます。
    • t.Fatal(args ...interface{}): t.Errorと同様にメッセージを出力し、t.FailNow()を呼び出してテスト関数を終了させます。
    • t.Fatalf(format string, args ...interface{}): t.Errorfと同様にフォーマットされたメッセージを出力し、t.FailNow()を呼び出してテスト関数を終了させます。

このコミットでは、t.Errorfからt.Errorへの変更が行われており、これはメッセージのフォーマット方法のみが変更され、テストの継続性には影響がないことを示唆しています。

strconvパッケージ

strconvパッケージは、Go言語の標準ライブラリの一部であり、文字列と基本的なデータ型(数値、真偽値など)との間の変換機能を提供します。例えば、文字列を整数に変換するAtoiや、浮動小数点数を文字列に変換するFormatFloat(またはその前身となる関数)などが含まれます。

このコミットで変更されたtestfp.gotestftoa.goは、それぞれ浮動小数点数(fpはfloating pointの略)の変換テストと、浮動小数点数をASCII文字列に変換する(ftoaはfloat to ASCIIの略)関数のテストに関連するファイルです。

技術的詳細

このコミットの技術的詳細は、testing.TErrorErrorfメソッドの挙動の違いに集約されます。

Go言語のtestingパッケージの初期の設計では、t.Errort.Errorfはどちらもテストを失敗としてマークしますが、メッセージの出力方法が異なります。

  • t.Errorは、可変長引数を受け取り、それらをfmt.Printlnのようにスペース区切りで連結して出力します。これは、単純な値の羅列や、既に整形された文字列を出力する場合に適しています。
  • t.Errorfは、C言語のprintf関数に似たフォーマット文字列と可変長引数を受け取り、それらを組み合わせて整形された文字列を出力します。これは、複雑なメッセージや、複数の変数の値を組み合わせて出力する場合に強力です。

このコミットでは、testfp.gotestftoa.go内の複数の箇所でt.Errorft.Errorに置き換えられています。元のt.Errorfの呼び出しを見ると、多くの場合、フォーマット文字列が不要な、あるいは単純な連結で済むような引数の渡し方をしていました。

例えば、t.Errorf("testfp.txt:", lineno, ": wrong field count\\n")という記述は、t.Error("testfp.txt:", lineno, ": wrong field count\\n")とすることで、同じ出力結果を得られます。この場合、Errorfの持つフォーマット機能は活用されておらず、冗長であると判断された可能性があります。

この変更は、コードの簡潔性を高め、不必要なフォーマット機能の使用を避けるためのリファクタリングと見なすことができます。また、Go言語の初期段階において、APIの適切な使用方法やコーディング規約が確立されていく過程の一部であったとも考えられます。

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

src/lib/strconv/testfp.go

--- a/src/lib/strconv/testfp.go
+++ b/src/lib/strconv/testfp.go
@@ -118,7 +118,7 @@ export func TestFp(t *testing.T) {
 		}
 		a := strings.split(line, " ");
 		if len(a) != 4 {
-			t.Errorf("testfp.txt:", lineno, ": wrong field count\n");
+			t.Error("testfp.txt:", lineno, ": wrong field count\n");
 			continue;
 		}
 		var s string;
@@ -128,21 +128,21 @@ export func TestFp(t *testing.T) {
 		case "float64":
 			var ok bool;
 			v, ok = myatof64(a[2]);
 			if !ok {
-				t.Errorf("testfp.txt:", lineno, ": cannot atof64 ", a[2]);
+				t.Error("testfp.txt:", lineno, ": cannot atof64 ", a[2]);
 				continue;
 			}
 			s = fmt.sprintf(a[1], v);
 		case "float32":
 			v1, ok := myatof32(a[2]);
 			if !ok {
-				t.Errorf("testfp.txt:", lineno, ": cannot atof32 ", a[2]);
+				t.Error("testfp.txt:", lineno, ": cannot atof32 ", a[2]);
 				continue;
 			}
 			s = fmt.sprintf(a[1], v1);
 			v = float64(v1);
 		}
 		if s != a[3] {
-			t.Errorf("testfp.txt:", lineno, ": ", a[0], " ", a[1], " ", a[2], " (", v, ") ",
+			t.Error("testfp.txt:", lineno, ": ", a[0], " ", a[1], " ", a[2], " (", v, ") ",
 				"want ", a[3], " got ", s, "\n");
 		}
 //else print("testfp.txt:", lineno, ": worked! ", s, "\n");

src/lib/strconv/testftoa.go

--- a/src/lib/strconv/testftoa.go
+++ b/src/lib/strconv/testftoa.go
@@ -98,12 +98,12 @@ export func TestFtoa(t *testing.T) {
 		test := &ftests[i];
 		s := strconv.ftoa64(test.f, test.fmt, test.prec);
 		if s != test.s {
-			t.Errorf("test", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
+			t.Error("test", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
 		}
 		if float64(float32(test.f)) == test.f && test.fmt != 'b' {
 			s := strconv.ftoa32(float32(test.f), test.fmt, test.prec);
 			if s != test.s {
-				t.Errorf("test32", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
+				t.Error("test32", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
 			}
 		}
 	}

コアとなるコードの解説

上記の差分が示す通り、変更は非常に単純です。t.Errorfの呼び出しが、対応するt.Errorの呼び出しに置き換えられています。

例えば、src/lib/strconv/testfp.goの最初の変更箇所では、以下の行が変更されています。

-			t.Errorf("testfp.txt:", lineno, ": wrong field count\n");
+			t.Error("testfp.txt:", lineno, ": wrong field count\n");

元のt.Errorfの呼び出しでは、第一引数にフォーマット文字列が与えられていますが、その内容は固定文字列と変数(lineno)をカンマで区切って並べたものであり、%s%dのようなフォーマット指示子は使用されていません。このような場合、t.Errorfは内部的に引数をfmt.Sprint(またはそれに類するもの)で処理し、結果としてt.Errorと同じようにスペース区切りで出力します。

したがって、この変更は機能的な違いをもたらすものではなく、コードの意図をより明確にし、不必要なフォーマット機能の使用を避けるためのクリーンアップであると考えられます。これは、Go言語の初期開発段階におけるコードベースの成熟と、API使用のベストプラクティスの確立に向けた一歩と言えるでしょう。

関連リンク

参考にした情報源リンク

  • Go言語の公式Gitリポジトリ: https://github.com/golang/go
  • Go言語の初期のコミット履歴(GitHub経由でアクセス可能)
  • Go言語のtestingパッケージに関する一般的な情報源(Stack Overflow, Goブログなど)
  • fmtパッケージのドキュメント(fmt.Printfmt.Printfの挙動理解のため)# [インデックス 1200] ファイルの概要

このコミットは、Go言語の標準ライブラリstrconvパッケージ内のテストファイルtestfp.gotestftoa.goにおける、テスト失敗報告関数の修正に関するものです。具体的には、testing.T型のメソッドであるErrorfの呼び出しがErrorに置き換えられています。

コミット

commit 64023e7b7d8ce78af2f08564dfcccca243a64a17
Author: Rob Pike <r@golang.org>
Date:   Wed Nov 19 18:43:04 2008 -0800

    a few Errorfs should have been Error
    
    R=rsc
    DELTA=6  (0 added, 0 deleted, 6 changed)
    OCL=19662
    CL=19664

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

https://github.com/golang/go/commit/64023e7b7d8ce78af2f08564dfcccca243a64a17

元コミット内容

このコミットは、Go言語の初期段階におけるtestingパッケージのAPI使用に関する修正です。コミットメッセージ「a few Errorfs should have been Error」が示す通り、テストコード内で誤ってt.Errorfが使われていた箇所をt.Errorに修正しています。

変更されたファイルは以下の2つです。

  • src/lib/strconv/testfp.go
  • src/lib/strconv/testftoa.go

これらのファイルでは、テストが失敗した場合にエラーメッセージを出力するためにt.Errorfが使用されていましたが、これがt.Errorに統一されました。

変更の背景

Go言語のtestingパッケージは、テストの実行と結果報告のための基本的な機能を提供します。testing.T型は、個々のテスト関数に渡される構造体で、テストのステータスを報告するための様々なメソッド(例: Error, Errorf, Fatal, Fatalfなど)を提供します。

このコミットが行われた2008年11月は、Go言語がまだ一般に公開される前の非常に初期の段階でした。この時期は、言語仕様や標準ライブラリのAPIが活発に設計・変更されていた過渡期にあたります。

t.Errort.Errorfはどちらもテストを失敗としてマークし、指定されたメッセージを出力しますが、そのメッセージのフォーマット方法に違いがあります。

  • t.Error(args ...interface{}): 引数をスペースで区切って出力します。fmt.Printlnのように動作します。
  • t.Errorf(format string, args ...interface{}): fmt.Printfと同様に、フォーマット文字列と引数を使ってメッセージを整形して出力します。

このコミットの背景には、おそらくtestingパッケージのAPI設計における初期の揺れや、特定の状況下でのErrorErrorfの使い分けに関する規約の確立があったと考えられます。この修正は、テストコード内でのエラー報告の一貫性を保つため、または特定のケースでErrorfのフォーマット機能が不要であると判断されたために行われた可能性があります。

前提知識の解説

Go言語のtestingパッケージ

Go言語には、標準でテストをサポートするためのtestingパッケージが用意されています。このパッケージを使用することで、ユニットテストやベンチマークテストを簡単に記述・実行できます。

  • テスト関数: func TestXxx(t *testing.T)というシグネチャを持つ関数がテスト関数として認識されます。Xxxの部分は任意の英数字の並びです。
  • *testing.T: テスト関数に渡される*testing.T型の引数は、テストの実行中にテストの状態を管理し、エラーを報告するためのメソッドを提供します。
  • エラー報告メソッド:
    • t.Error(args ...interface{}): テストを失敗としてマークし、引数をスペース区切りで出力します。テストの実行は継続されます。
    • t.Errorf(format string, args ...interface{}): テストを失敗としてマークし、fmt.Printf形式でフォーマットされたメッセージを出力します。テストの実行は継続されます。
    • t.Fail(): テストを失敗としてマークしますが、メッセージは出力しません。テストの実行は継続されます。
    • t.FailNow(): テストを失敗としてマークし、現在のテスト関数を即座に終了させます。
    • t.Fatal(args ...interface{}): t.Errorと同様にメッセージを出力し、t.FailNow()を呼び出してテスト関数を終了させます。
    • t.Fatalf(format string, args ...interface{}): t.Errorfと同様にフォーマットされたメッセージを出力し、t.FailNow()を呼び出してテスト関数を終了させます。

このコミットでは、t.Errorfからt.Errorへの変更が行われており、これはメッセージのフォーマット方法のみが変更され、テストの継続性には影響がないことを示唆しています。

strconvパッケージ

strconvパッケージは、Go言語の標準ライブラリの一部であり、文字列と基本的なデータ型(数値、真偽値など)との間の変換機能を提供します。例えば、文字列を整数に変換するAtoiや、浮動小数点数を文字列に変換するFormatFloat(またはその前身となる関数)などが含まれます。

このコミットで変更されたtestfp.gotestftoa.goは、それぞれ浮動小数点数(fpはfloating pointの略)の変換テストと、浮動小数点数をASCII文字列に変換する(ftoaはfloat to ASCIIの略)関数のテストに関連するファイルです。

技術的詳細

このコミットの技術的詳細は、testing.TErrorErrorfメソッドの挙動の違いに集約されます。

Go言語のtestingパッケージの初期の設計では、t.Errort.Errorfはどちらもテストを失敗としてマークしますが、メッセージの出力方法が異なります。

  • t.Errorは、可変長引数を受け取り、それらをfmt.Printlnのようにスペース区切りで連結して出力します。これは、単純な値の羅列や、既に整形された文字列を出力する場合に適しています。
  • t.Errorfは、C言語のprintf関数に似たフォーマット文字列と可変長引数を受け取り、それらを組み合わせて整形された文字列を出力します。これは、複雑なメッセージや、複数の変数の値を組み合わせて出力する場合に強力です。

このコミットでは、testfp.gotestftoa.go内の複数の箇所でt.Errorft.Errorに置き換えられています。元のt.Errorfの呼び出しを見ると、多くの場合、フォーマット文字列が不要な、あるいは単純な連結で済むような引数の渡し方をしていました。

例えば、t.Errorf("testfp.txt:", lineno, ": wrong field count\n")という記述は、t.Error("testfp.txt:", lineno, ": wrong field count\n")とすることで、同じ出力結果を得られます。この場合、Errorfの持つフォーマット機能は活用されておらず、冗長であると判断された可能性があります。

したがって、この変更は機能的な違いをもたらすものではなく、コードの意図をより明確にし、不必要なフォーマット機能の使用を避けるためのクリーンアップであると考えられます。また、Go言語の初期段階において、APIの適切な使用方法やコーディング規約が確立されていく過程の一部であったとも考えられます。

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

src/lib/strconv/testfp.go

--- a/src/lib/strconv/testfp.go
+++ b/src/lib/strconv/testfp.go
@@ -118,7 +118,7 @@ export func TestFp(t *testing.T) {
 		}
 		a := strings.split(line, " ");
 		if len(a) != 4 {
-			t.Errorf("testfp.txt:", lineno, ": wrong field count\n");
+			t.Error("testfp.txt:", lineno, ": wrong field count\n");
 			continue;
 		}
 		var s string;
@@ -128,21 +128,21 @@ export func TestFp(t *testing.T) {
 		case "float64":
 			var ok bool;
 			v, ok = myatof64(a[2]);
 			if !ok {
-				t.Errorf("testfp.txt:", lineno, ": cannot atof64 ", a[2]);
+				t.Error("testfp.txt:", lineno, ": cannot atof64 ", a[2]);
 				continue;
 			}
 			s = fmt.sprintf(a[1], v);
 		case "float32":
 			v1, ok := myatof32(a[2]);
 			if !ok {
-				t.Errorf("testfp.txt:", lineno, ": cannot atof32 ", a[2]);
+				t.Error("testfp.txt:", lineno, ": cannot atof32 ", a[2]);
 				continue;
 			}
 			s = fmt.sprintf(a[1], v1);
 			v = float64(v1);
 		}
 		if s != a[3] {
-			t.Errorf("testfp.txt:", lineno, ": ", a[0], " ", a[1], " ", a[2], " (", v, ") ",
+			t.Error("testfp.txt:", lineno, ": ", a[0], " ", a[1], " ", a[2], " (", v, ") ",
 				"want ", a[3], " got ", s, "\n");
 		}
 //else print("testfp.txt:", lineno, ": worked! ", s, "\n");

src/lib/strconv/testftoa.go

--- a/src/lib/strconv/testftoa.go
+++ b/src/lib/strconv/testftoa.go
@@ -98,12 +98,12 @@ export func TestFtoa(t *testing.T) {
 		test := &ftests[i];
 		s := strconv.ftoa64(test.f, test.fmt, test.prec);
 		if s != test.s {
-			t.Errorf("test", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
+			t.Error("test", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
 		}
 		if float64(float32(test.f)) == test.f && test.fmt != 'b' {
 			s := strconv.ftoa32(float32(test.f), test.fmt, test.prec);
 			if s != test.s {
-				t.Errorf("test32", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
+				t.Error("test32", test.f, string(test.fmt), test.prec, "want", test.s, "got", s);
 			}
 		}
 	}

コアとなるコードの解説

上記の差分が示す通り、変更は非常に単純です。t.Errorfの呼び出しが、対応するt.Errorの呼び出しに置き換えられています。

例えば、src/lib/strconv/testfp.goの最初の変更箇所では、以下の行が変更されています。

-			t.Errorf("testfp.txt:", lineno, ": wrong field count\n");
+			t.Error("testfp.txt:", lineno, ": wrong field count\n");

元のt.Errorfの呼び出しでは、第一引数にフォーマット文字列が与えられていますが、その内容は固定文字列と変数(lineno)をカンマで区切って並べたものであり、%s%dのようなフォーマット指示子は使用されていません。このような場合、t.Errorfは内部的に引数をfmt.Sprint(またはそれに類するもの)で処理し、結果としてt.Errorと同じようにスペース区切りで出力します。

したがって、この変更は機能的な違いをもたらすものではなく、コードの意図をより明確にし、不必要なフォーマット機能の使用を避けるためのクリーンアップであると考えられます。これは、Go言語の初期開発段階におけるコードベースの成熟と、API使用のベストプラクティスの確立に向けた一歩と言えるでしょう。

関連リンク

参考にした情報源リンク

  • Go言語の公式Gitリポジトリ: https://github.com/golang/go
  • Go言語の初期のコミット履歴(GitHub経由でアクセス可能)
  • Go言語のtestingパッケージに関する一般的な情報源(Stack Overflow, Goブログなど)
  • fmtパッケージのドキュメント(fmt.Printfmt.Printfの挙動理解のため)