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

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

このコミットは、Go言語の初期段階におけるuntab.goファイルのコンパイルエラーを修正したものです。具体的には、関数名のキャメルケースからスネークケース(または非エクスポート名)への変更と、fmtパッケージ内の関数名の修正が含まれています。これは、Go言語の命名規則の進化と、標準ライブラリのAPI変更の初期の例を示しています。

コミット

commit 2ab55776b5e7c5c1336af3a3234974b31c99af1e
Author: Robert Griesemer <gri@golang.org>
Date:   Thu Jan 15 15:14:19 2009 -0800

    - fixed untab.go to compile again
    
    R=r
    OCL=22871
    CL=22871

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

https://github.com/golang/go/commit/2ab55776b5e7c5c1336af3a3234974b31c99af1e

元コミット内容

このコミットは、untab.goというファイルがコンパイルできなくなった問題を修正することを目的としています。具体的な変更内容は、関数名の変更と、fmtパッケージの関数呼び出しの修正です。

変更の背景

Go言語は2009年にGoogleで開発が始まり、このコミットは非常に初期の段階(2009年1月)に行われたものです。言語仕様や標準ライブラリのAPIはまだ流動的であり、頻繁に変更されていました。この時期には、Goの命名規則(エクスポートされる識別子は大文字で始まり、エクスポートされない識別子は小文字で始まる)が確立されつつあり、それに合わせて既存のコードベースが修正されていました。

untab.goは、おそらくタブをスペースに変換するユーティリティのようなもので、Go言語の初期のツールセットの一部だったと考えられます。コンパイルエラーが発生したということは、Goコンパイラまたは標準ライブラリの変更によって、以前のコードが不正になったことを意味します。このコミットは、これらの変更に適応するための修正です。

前提知識の解説

Go言語の命名規則

Go言語には、識別子の可視性(エクスポートされるか否か)を制御するための明確な命名規則があります。

  • エクスポートされる識別子: パッケージ外からアクセス可能にするには、識別子(変数、関数、型など)の名前を大文字で始める必要があります。
  • エクスポートされない識別子: パッケージ内でのみ使用される識別子は、小文字で始める必要があります。

この規則は、Go言語のモジュール性とカプセル化の重要な側面であり、コードの意図を明確にし、APIの安定性を保つのに役立ちます。

fmtパッケージ

fmtパッケージは、Go言語におけるフォーマットされたI/O(入力/出力)を実装するための標準ライブラリです。C言語のprintfscanfに似た機能を提供し、文字列、数値、その他のデータ型を整形して出力したり、入力から解析したりするために使用されます。

初期のGo言語では、fmt.printfのような関数名が使われていた可能性がありますが、後にGoの命名規則やAPI設計の慣習に合わせてfmt.Printfのように変更されたと考えられます。Goの標準ライブラリの関数は、通常、エクスポートされるため、大文字で始まる名前が付けられます。

io.Copy関数

io.Copy(dst, src)関数は、Go言語のioパッケージで提供されるユーティリティ関数です。src(ソース)からdst(デスティネーション)へデータをコピーします。これは、ファイルからファイルへ、ネットワーク接続からファイルへ、またはその逆など、様々なI/Oストリーム間でデータを効率的に転送するために使用されます。

技術的詳細

このコミットの技術的な詳細は、Go言語の初期のコンパイラと標準ライブラリの進化に密接に関連しています。

  1. 関数名の変更:

    • func Error(...) から func error(...)
    • func Untab(...) から func untab(...)

    この変更は、Go言語の命名規則が適用された結果です。ErrorUntabは、おそらくパッケージ内部でのみ使用されるべき関数であったため、外部にエクスポートされないように小文字で始まる名前に変更されました。これにより、これらの関数が外部から誤って呼び出されることを防ぎ、APIの意図を明確にしています。

  2. fmt.printf から fmt.Printf への変更:

    • fmt.printf(format, params) から fmt.Printf(format, params)

    これは、fmtパッケージ内のフォーマット出力関数が、Goのエクスポート規則に従ってPrintf(Print Formatted)という大文字で始まる名前に変更されたことを示しています。Printfは、Go言語で最も一般的に使用されるフォーマット出力関数の一つであり、この変更は標準ライブラリのAPIが成熟していく過程の一部です。

  3. エラーハンドリングの呼び出し元の修正:

    • Error(...) の呼び出しが error(...) に変更されています。

    これは、Error関数の名前がerrorに変更されたことに伴う、呼び出し側の修正です。これにより、コードベース全体で一貫性が保たれ、コンパイルエラーが解消されます。

これらの変更は、Go言語がその設計原則(シンプルさ、明確さ、効率性)を確立していく過程で、コードベース全体にわたって行われた多くの調整の一つです。

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

変更はusr/gri/pretty/untab.goファイルに集中しています。

--- a/usr/gri/pretty/untab.go
+++ b/usr/gri/pretty/untab.go
@@ -19,16 +19,16 @@ var (
 )
 
 
-func Error(format string, params ...) {
-\tfmt.printf(format, params);
+func error(format string, params ...) {
+\tfmt.Printf(format, params);
 \tsys.exit(1);\n }
 
 
-func Untab(name string, src *os.FD, dst *tabwriter.Writer) {
+func untab(name string, src *os.FD, dst *tabwriter.Writer) {
 \tn, err := io.Copy(src, dst);\n \tif err != nil {\n-\t\tError(\"error while processing %s (%v)\", name, err);\n+\t\terror(\"error while processing %s (%v)\", name, err);\n \t}\n \t//dst.Flush();\n }\n@@ -46,13 +46,13 @@ func main() {\n \t\t\tname := flag.Arg(i);\n \t\t\tsrc, err := os.Open(name, os.O_RDONLY, 0);\n \t\t\tif err != nil {\n-\t\t\t\tError(\"could not open %s (%v)\\n\", name, err);\n+\t\t\t\terror(\"could not open %s (%v)\\n\", name, err);\n \t\t\t}\n-\t\t\tUntab(name, src, dst);\n+\t\t\tuntab(name, src, dst);\n \t\t\tsrc.Close();  // ignore errors\n \t\t}\n \t} else {\n \t\t// no files => use stdin\n-\t\tUntab(\"/dev/stdin\", os.Stdin, dst);\n+\t\tuntab(\"/dev/stdin\", os.Stdin, dst);\n \t}\n }\n```

## コアとなるコードの解説

このコミットでは、以下の3つの主要な変更が行われています。

1.  **`Error`関数のリネームと`fmt.printf`の修正**:
    ```go
    -func Error(format string, params ...) {
    -	fmt.printf(format, params);
    +func error(format string, params ...) {
    +	fmt.Printf(format, params);
    	sys.exit(1);
    }
    ```
    `Error`関数が`error`にリネームされ、同時に`fmt.printf`が`fmt.Printf`に修正されています。これは、`error`関数がパッケージ内部でのみ使用されることを意図しており、Goの命名規則に従って小文字で始まる名前に変更されたことを示しています。また、`fmt`パッケージのフォーマット出力関数が`Printf`というエクスポートされた名前に統一されたことを反映しています。

2.  **`Untab`関数のリネームと内部呼び出しの修正**:
    ```go
    -func Untab(name string, src *os.FD, dst *tabwriter.Writer) {
    +func untab(name string, src *os.FD, dst *tabwriter.Writer) {
    	n, err := io.Copy(src, dst);
    	if err != nil {
    -		Error("error while processing %s (%v)", name, err);
    +		error("error while processing %s (%v)", name, err);
    	}
    	//dst.Flush();
    }
    ```
    `Untab`関数も`untab`にリネームされています。これは`error`関数と同様に、パッケージ内部でのみ使用されることを示すための変更です。また、この関数内で以前`Error`を呼び出していた箇所が、新しい`error`関数を呼び出すように修正されています。

3.  **`main`関数内の`Untab`呼び出しの修正**:
    ```go
    // ... (省略) ...
    			if err != nil {
    -				Error("could not open %s (%v)\n", name, err);
    +				error("could not open %s (%v)\n", name, err);
    			}
    -			Untab(name, src, dst);
    +			untab(name, src, dst);
    			src.Close();  // ignore errors
    		}
    	} else {
    		// no files => use stdin
    -		Untab("/dev/stdin", os.Stdin, dst);
    +		untab("/dev/stdin", os.Stdin, dst);
    	}
    }
    ```
    `main`関数内で`Untab`関数が呼び出されているすべての箇所が、新しい`untab`関数を呼び出すように修正されています。同様に、エラー処理のために`Error`関数を呼び出していた箇所も`error`関数を呼び出すように変更されています。

これらの変更は、Go言語の初期のコードベースが、言語の進化と命名規則の確立に合わせてどのように適応していったかを示す良い例です。

## 関連リンク

*   Go言語の公式ドキュメント: [https://go.dev/doc/](https://go.dev/doc/)
*   Go言語の命名規則に関する公式ガイドライン(Effective Go): [https://go.dev/doc/effective_go#names](https://go.dev/doc/effective_go#names)
*   `fmt`パッケージのドキュメント: [https://pkg.go.dev/fmt](https://pkg.go.dev/fmt)
*   `io`パッケージのドキュメント: [https://pkg.go.dev/io](https://pkg.go.dev/io)

## 参考にした情報源リンク

*   Go言語の初期のコミット履歴 (GitHub): [https://github.com/golang/go/commits/master](https://github.com/golang/go/commits/master)
*   Go言語のリリースノートやブログ記事(初期の言語変更に関する情報が含まれる可能性)
*   Go言語の設計に関する議論やメーリングリストのアーカイブ(初期の設計決定に関する情報が含まれる可能性)
*   Go言語の命名規則に関する一般的な解説記事やチュートリアル