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

[インデックス 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言語の基本的な概念を理解しておく必要があります。

  1. Go言語の命名規則(Exported vs. Unexported Identifiers):

    • Go言語では、識別子(変数名、関数名、型名、メソッド名など)の最初の文字が大文字であるか小文字であるかによって、その可視性(スコープ)が決定されます。
    • 大文字で始まる識別子: パッケージの外部からアクセス可能です。これらは「エクスポートされた(exported)」識別子と呼ばれ、公開APIの一部となります。
    • 小文字で始まる識別子: その識別子が定義されているパッケージ内でのみアクセス可能です。これらは「非エクスポートの(unexported)」識別子と呼ばれ、パッケージの内部実装の詳細を隠蔽するために使用されます。
    • この規則は、Goのシンプルさと明示性を重視する設計哲学の一部であり、APIの設計において非常に重要です。
  2. tabwriter パッケージ:

    • text/tabwriter パッケージは、Goの標準ライブラリの一部であり、テキストデータを整形して、列がタブで揃うようにするための機能を提供します。これは、コマンドラインツールやログ出力などで、整形された表形式のデータを表示する際に非常に便利です。
    • 内部的には、tabwriter は入力されたバイトストリームを処理し、タブ文字や改行文字に基づいてセルの幅を計算し、適切なパディングを追加して出力を生成します。
  3. io.Writer インターフェース:

    • Go言語における基本的なI/Oインターフェースの一つです。Write([]byte) (n int, err error) メソッドを持つ型は io.Writer インターフェースを満たします。
    • tabwriter.Writerio.Writer を実装しており、他の io.Writer (例: os.Stdoutbytes.Buffer)に整形されたテキストを書き込むことができます。

技術的詳細

このコミットは、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() intfunc (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言語の可視性ルール(エクスポート/非エクスポート)をコードに適用することです。

  1. メソッド定義の変更:

    • func (b *byteArray) Init(initial_size int)func (b *byteArray) init(initial_size int) に変更されました。
    • func (b *byteArray) Len() intfunc (b *byteArray) len() int に変更されました。
    • これにより、byteArray 型の initlen メソッドは、tabwriter パッケージの外部からは直接呼び出せなくなります。これらは byteArray の内部的な状態管理のためのヘルパーメソッドであり、外部に公開する必要がないため、適切な変更です。
  2. メソッド呼び出しの変更:

    • b.buf.Init(1024) のような Init メソッドの呼び出しは b.buf.init(1024) に変更されました。
    • b.buf.Len() のような Len メソッドの呼び出しは b.buf.len() に変更されました。
    • これらの変更は、メソッド名の変更に伴う必然的な修正です。b.buftabwriter.Writer 構造体内の byteArray 型のフィールドであり、その内部メソッドが呼び出されています。

この変更は、Go言語の設計原則である「明示性」と「カプセル化」を強化します。非公開のメソッドを小文字で始めることで、開発者はそのメソッドがパッケージの内部実装の一部であり、外部から直接操作すべきではないことを一目で理解できます。これにより、APIの誤用を防ぎ、コードベースの健全性を維持するのに役立ちます。

関連リンク

参考にした情報源リンク