[インデックス 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言語のprintf
やscanf
に似た機能を提供し、文字列、数値、その他のデータ型を整形して出力したり、入力から解析したりするために使用されます。
初期のGo言語では、fmt.printf
のような関数名が使われていた可能性がありますが、後にGoの命名規則やAPI設計の慣習に合わせてfmt.Printf
のように変更されたと考えられます。Goの標準ライブラリの関数は、通常、エクスポートされるため、大文字で始まる名前が付けられます。
io.Copy
関数
io.Copy(dst, src)
関数は、Go言語のio
パッケージで提供されるユーティリティ関数です。src
(ソース)からdst
(デスティネーション)へデータをコピーします。これは、ファイルからファイルへ、ネットワーク接続からファイルへ、またはその逆など、様々なI/Oストリーム間でデータを効率的に転送するために使用されます。
技術的詳細
このコミットの技術的な詳細は、Go言語の初期のコンパイラと標準ライブラリの進化に密接に関連しています。
-
関数名の変更:
func Error(...)
からfunc error(...)
へfunc Untab(...)
からfunc untab(...)
へ
この変更は、Go言語の命名規則が適用された結果です。
Error
とUntab
は、おそらくパッケージ内部でのみ使用されるべき関数であったため、外部にエクスポートされないように小文字で始まる名前に変更されました。これにより、これらの関数が外部から誤って呼び出されることを防ぎ、APIの意図を明確にしています。 -
fmt.printf
からfmt.Printf
への変更:fmt.printf(format, params)
からfmt.Printf(format, params)
へ
これは、
fmt
パッケージ内のフォーマット出力関数が、Goのエクスポート規則に従ってPrintf
(Print Formatted)という大文字で始まる名前に変更されたことを示しています。Printf
は、Go言語で最も一般的に使用されるフォーマット出力関数の一つであり、この変更は標準ライブラリのAPIが成熟していく過程の一部です。 -
エラーハンドリングの呼び出し元の修正:
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言語の命名規則に関する一般的な解説記事やチュートリアル