[インデックス 1800] ファイルの概要
このコミットは、Go言語の標準ライブラリの一部である tabwriter
パッケージ内の内部メソッドの命名規則を修正するものです。具体的には、byteArray
型の Init
および Len
メソッドが、Goの命名規則に従い、それぞれ init
および len
に変更されています。これは、これらのメソッドがパッケージ外部からアクセスされることを意図しない、つまり「非公開」であることを明確にするための変更です。
コミット
commit 915f176f7f57b931d90f1b86f254fd7ddc9e15d3
Author: Robert Griesemer <gri@golang.org>
Date: Tue Mar 10 18:09:13 2009 -0700
- fixing (internal) capitalization
R=rsc
DELTA=7 (0 added, 0 deleted, 7 changed)
OCL=26080
CL=26080
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/915f176f7f57b931d90f1b86f254fd7ddc9e15d3
元コミット内容
- fixing (internal) capitalization
変更の背景
このコミットの背景には、Go言語の設計思想における重要な原則の一つである「エクスポートされた識別子(Exported Identifiers)」の命名規則があります。Goでは、パッケージの外部からアクセス可能な(エクスポートされた)関数、変数、型、メソッドなどは、その名前が大文字で始まる必要があります。一方、パッケージ内部でのみ使用される(非エクスポートの、または内部の)識別子は、小文字で始まります。
tabwriter
パッケージは、テキストをタブで揃えて整形するためのユーティリティを提供します。このコミットが行われた2009年3月は、Go言語がまだ初期開発段階にあり、言語仕様や標準ライブラリのAPIが活発に洗練されていた時期です。
byteArray
型の Init
および Len
メソッドは、tabwriter
パッケージの内部実装の詳細であり、外部から直接呼び出されることを意図していませんでした。しかし、初期のコードではこれらが大文字で始まっており、Goの命名規則に反していました。このコミットは、この不整合を修正し、これらのメソッドが内部的なものであることを明確にするために行われました。これにより、コードの意図がより明確になり、将来的なAPIの誤用を防ぐことができます。
前提知識の解説
このコミットを理解するためには、以下のGo言語の基本的な概念を理解しておく必要があります。
-
Go言語の命名規則(Exported vs. Unexported Identifiers):
- Go言語では、識別子(変数名、関数名、型名、メソッド名など)の最初の文字が大文字であるか小文字であるかによって、その可視性(スコープ)が決定されます。
- 大文字で始まる識別子: パッケージの外部からアクセス可能です。これらは「エクスポートされた(exported)」識別子と呼ばれ、公開APIの一部となります。
- 小文字で始まる識別子: その識別子が定義されているパッケージ内でのみアクセス可能です。これらは「非エクスポートの(unexported)」識別子と呼ばれ、パッケージの内部実装の詳細を隠蔽するために使用されます。
- この規則は、Goのシンプルさと明示性を重視する設計哲学の一部であり、APIの設計において非常に重要です。
-
tabwriter
パッケージ:text/tabwriter
パッケージは、Goの標準ライブラリの一部であり、テキストデータを整形して、列がタブで揃うようにするための機能を提供します。これは、コマンドラインツールやログ出力などで、整形された表形式のデータを表示する際に非常に便利です。- 内部的には、
tabwriter
は入力されたバイトストリームを処理し、タブ文字や改行文字に基づいてセルの幅を計算し、適切なパディングを追加して出力を生成します。
-
io.Writer
インターフェース:- Go言語における基本的なI/Oインターフェースの一つです。
Write([]byte) (n int, err error)
メソッドを持つ型はio.Writer
インターフェースを満たします。 tabwriter.Writer
はio.Writer
を実装しており、他のio.Writer
(例:os.Stdout
やbytes.Buffer
)に整形されたテキストを書き込むことができます。
- Go言語における基本的なI/Oインターフェースの一つです。
技術的詳細
このコミットは、src/lib/tabwriter/tabwriter.go
ファイル内の byteArray
という内部ヘルパー型のメソッド名を変更しています。
byteArray
は、tabwriter
パッケージが内部的にバイトスライスを管理するために使用する構造体です。この構造体には、バイトスライスの初期化 (Init
) や長さの取得 (Len
) といった基本的な操作を行うメソッドが含まれていました。
Goの命名規則に従うと、これらのメソッドがパッケージの外部に公開されるべきではない場合、その名前は小文字で始まるべきです。このコミットでは、まさにその修正が行われました。
func (b *byteArray) Init(initial_size int)
はfunc (b *byteArray) init(initial_size int)
に変更されました。func (b *byteArray) Len() int
はfunc (b *byteArray) len() int
に変更されました。
これらの変更に伴い、tabwriter.go
ファイル内でこれらのメソッドが呼び出されている箇所もすべて更新されています。例えば、b.buf.Init(1024)
は b.buf.init(1024)
に、b.buf.Len()
は b.buf.len()
に変更されています。
この変更は、機能的な振る舞いを一切変更せず、純粋にコードの可読性とGoの慣習への準拠を向上させるためのものです。このような内部的な命名規則の統一は、大規模なプロジェクトにおいてコードベースの一貫性を保ち、新しい開発者がコードを理解しやすくするために非常に重要です。
コアとなるコードの変更箇所
変更は src/lib/tabwriter/tabwriter.go
ファイルに集中しています。
--- a/src/lib/tabwriter/tabwriter.go
+++ b/src/lib/tabwriter/tabwriter.go
@@ -25,12 +25,12 @@ type byteArray struct {
}
-func (b *byteArray) Init(initial_size int) {
+func (b *byteArray) init(initial_size int) {
b.a = make([]byte, initial_size)[0 : 0];
}
-func (b *byteArray) Len() int {
+func (b *byteArray) len() int {
return len(b.a);
}
@@ -188,7 +188,7 @@ func (b *Writer) Init(output io.Write, cellwidth, padding int, padchar byte, fla
}
b.flags = flags;
- b.buf.Init(1024);
+ b.buf.init(1024);
b.lines_size.Init(0);
b.lines_width.Init(0);
b.widths.Init(0);
@@ -424,8 +424,8 @@ func (b *Writer) Write(buf []byte) (written int, err *os.Error) {
case '\t', '\n':
b.append(buf[i0 : i]);
i0 = i + 1; // exclude ch from (next) cell
- b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
- b.pos = b.buf.Len();
+ b.width += unicodeLen(b.buf.slice(b.pos, b.buf.len()));
+ b.pos = b.buf.len();
// terminate cell
last_size, last_width := b.line(b.lines_size.Len() - 1);
@@ -451,7 +451,7 @@ func (b *Writer) Write(buf []byte) (written int, err *os.Error) {
if b.flags & FilterHTML != 0 {
b.append(buf[i0 : i]);
i0 = i;
- b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
+ b.width += unicodeLen(b.buf.slice(b.pos, b.buf.len()));
b.pos = -1; // preventative - should not be used (will cause index out of bounds)
if ch == '<' {
b.html_char = '>';
@@ -470,7 +470,7 @@ func (b *Writer) Write(buf []byte) (written int, err *os.Error) {
if b.html_char == ';' {
b.width++; // count as one char
}
- b.pos = b.buf.Len();
+ b.pos = b.buf.len();
b.html_char = 0;
}
}
コアとなるコードの解説
このコミットの核心は、Go言語の可視性ルール(エクスポート/非エクスポート)をコードに適用することです。
-
メソッド定義の変更:
func (b *byteArray) Init(initial_size int)
がfunc (b *byteArray) init(initial_size int)
に変更されました。func (b *byteArray) Len() int
がfunc (b *byteArray) len() int
に変更されました。- これにより、
byteArray
型のinit
とlen
メソッドは、tabwriter
パッケージの外部からは直接呼び出せなくなります。これらはbyteArray
の内部的な状態管理のためのヘルパーメソッドであり、外部に公開する必要がないため、適切な変更です。
-
メソッド呼び出しの変更:
b.buf.Init(1024)
のようなInit
メソッドの呼び出しはb.buf.init(1024)
に変更されました。b.buf.Len()
のようなLen
メソッドの呼び出しはb.buf.len()
に変更されました。- これらの変更は、メソッド名の変更に伴う必然的な修正です。
b.buf
はtabwriter.Writer
構造体内のbyteArray
型のフィールドであり、その内部メソッドが呼び出されています。
この変更は、Go言語の設計原則である「明示性」と「カプセル化」を強化します。非公開のメソッドを小文字で始めることで、開発者はそのメソッドがパッケージの内部実装の一部であり、外部から直接操作すべきではないことを一目で理解できます。これにより、APIの誤用を防ぎ、コードベースの健全性を維持するのに役立ちます。
関連リンク
- Go言語の公式ドキュメント: https://golang.org/
text/tabwriter
パッケージのドキュメント (現在のバージョン): https://pkg.go.dev/text/tabwriter- Go言語の命名規則に関する公式ブログ記事 (例: Effective Go - Names): https://go.dev/doc/effective_go#names
参考にした情報源リンク
- GitHub上のコミットページ: https://github.com/golang/go/commit/915f176f7f57b931d90f1b86f254fd7ddc9e15d3
- Go言語の初期開発に関する情報 (Goの歴史など): https://go.dev/doc/history
- Go言語のEffective Goドキュメント: https://go.dev/doc/effective_go