[インデックス 1518] ファイルの概要
このコミットは、Go言語の初期開発段階におけるコードベースの一部変更を記録しています。具体的には、usr/gri/pretty
ディレクトリ内の複数のGoソースファイルにおいて、構造体(struct)のフィールド名の命名規則を修正しています。これは、Go言語におけるエクスポートされた(公開された)フィールドの命名規則に準拠させるための変更であり、フィールド名の先頭文字を小文字から大文字に「casify(ケースを変更する)」しています。
コミット
commit 626d25065dd5c0e99ddd7504567dab7fa5fa087c
Author: Robert Griesemer <gri@golang.org>
Date: Fri Jan 16 15:31:34 2009 -0800
casify struct fields
R=r
OCL=22998
CL=22998
--
usr/gri/pretty/ast.go | 6 +++---
usr/gri/pretty/compilation.go | 22 +++++++++++-----------
usr/gri/pretty/parser.go | 2 +--
usr/gri/pretty/pretty.go | 16 ++++++++--------
4 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go
index 29d183391e..84c404eb78 100644
--- a/usr/gri/pretty/ast.go
+++ b/usr/gri/pretty/ast.go
@@ -99,14 +99,14 @@ export func NewObject(pos, kind int, ident string) *Object {
// Scopes
export type Scope struct {
- parent *Scope;
+ Parent *Scope;
entries map[string] *Object;
}
export func NewScope(parent *Scope) *Scope {
scope := new(Scope);
- scope.parent = parent;
+ scope.Parent = parent;
scope.entries = make(map[string]*Object, 8);
return scope;
}
@@ -127,7 +127,7 @@ func (scope *Scope) Lookup(ident string) *Object {
if obj != nil {
return obj;
}
- scope = scope.parent;
+ scope = scope.Parent;
}
return nil;
}
diff --git a/usr/gri/pretty/compilation.go b/usr/gri/pretty/compilation.go
index ad802566f9..1d8f3cf1dd 100644
--- a/usr/gri/pretty/compilation.go
+++ b/usr/gri/pretty/compilation.go
@@ -24,13 +24,13 @@ func assert(b bool) {
export type Flags struct {
- verbose bool;
- sixg bool;
- deps bool;
- columns bool;
- testmode bool;
- tokenchan bool;
- naming bool;
+ Verbose bool;
+ Sixg bool;
+ Deps bool;
+ Columns bool;
+ Testmode bool;
+ Tokenchan bool;
+ Naming bool;
}
@@ -125,18 +125,18 @@ export func Compile(src_file string, flags *Flags) (*AST.Program, int) {
}
var err errorHandler;
- err.Init(src_file, src, flags.columns);
+ err.Init(src_file, src, flags.Columns);
var scanner Scanner.Scanner;
- scanner.Init(&err, src, true, flags.testmode);
+ scanner.Init(&err, src, true, flags.Testmode);
var tstream <-chan *Scanner.Token;
- if flags.tokenchan {
+ if flags.Tokenchan {
tstream = scanner.TokenStream();
}
var parser Parser.Parser;
- parser.Open(flags.verbose, flags.sixg, flags.deps, flags.naming, &scanner, tstream);
+ parser.Open(flags.Verbose, flags.Sixg, flags.Deps, flags.Naming, &scanner, tstream);
prog := parser.ParseProgram();
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index 1f975682e0..d72eeccd89 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -160,7 +160,7 @@ func (P *Parser) OpenScope() {
func (P *Parser) CloseScope() {
- P.top_scope = P.top_scope.parent;
+ P.top_scope = P.top_scope.Parent;
}
diff --git a/usr/gri/pretty/pretty.go b/usr/gri/pretty/pretty.go
index 1d6ad575f0..94233ee44d 100644
--- a/usr/gri/pretty/pretty.go
+++ b/usr/gri/pretty/pretty.go
@@ -18,14 +18,14 @@ var (\n )\n \n func init() {\n- Flag.BoolVar(&flags.verbose, \"v\", false, \"verbose mode: trace parsing\");\n- Flag.BoolVar(&flags.sixg, \"6g\", true, \"6g compatibility mode\");\n+ Flag.BoolVar(&flags.Verbose, \"v\", false, \"verbose mode: trace parsing\");\n+ Flag.BoolVar(&flags.Sixg, \"6g\", true, \"6g compatibility mode\");\n //TODO fix this code again\n- //Flag.BoolVar(&flags.deps, \"d\", false, \"print dependency information only\");\n- Flag.BoolVar(&flags.columns, \"columns\", Platform.USER == \"gri\", \"print column info in error messages\");\n- Flag.BoolVar(&flags.testmode, \"t\", false, \"test mode: interprets /* ERROR */ and /* SYNC */ comments\");\n- Flag.BoolVar(&flags.tokenchan, \"token_chan\", false, \"use token channel for scanner-parser connection\");\n- Flag.BoolVar(&flags.naming, \"naming\", false, \"verify export naming scheme\");\n+ //Flag.BoolVar(&flags.Deps, \"d\", false, \"print dependency information only\");\n+ Flag.BoolVar(&flags.Columns, \"columns\", Platform.USER == \"gri\", \"print column info in error messages\");\n+ Flag.BoolVar(&flags.Testmode, \"t\", false, \"test mode: interprets /* ERROR */ and /* SYNC */ comments\");\n+ Flag.BoolVar(&flags.Tokenchan, \"token_chan\", false, \"use token channel for scanner-parser connection\");\n+ Flag.BoolVar(&flags.Naming, \"naming\", false, \"verify export naming scheme\");\n }\n \n \n@@ -55,7 +55,7 @@ func main() {\n if nerrors > 0 {\n return;\n }\n- if !flags.naming && !*silent && !flags.testmode {\n+ if !flags.Naming && !*silent && !flags.Testmode {\n Printer.Print(prog);\n }\n }\n```
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/626d25065dd5c0e99ddd7504567dab7fa5fa087c](https://github.com/golang/go/commit/626d25065dd5c0e99ddd7504567dab7fa5fa087c)
## 元コミット内容
このコミットの元々のメッセージは「casify struct fields」です。これは、構造体のフィールド名をGo言語の命名規則に合わせて「ケースを変更する」、つまり小文字から大文字に変換することを意味しています。
## 変更の背景
Go言語は、その設計思想の一つとして「シンプルさ」と「明瞭さ」を重視しています。その一環として、識別子(変数名、関数名、型名、構造体フィールド名など)の可視性(エクスポートされるか否か)を、その識別子の先頭文字のケース(大文字か小文字か)によって決定するというユニークなルールを採用しています。
- **大文字で始まる識別子**: パッケージ外からアクセス可能(エクスポートされる)
- **小文字で始まる識別子**: パッケージ内でのみアクセス可能(エクスポートされない)
このコミットが行われた2009年1月は、Go言語がまだ一般に公開される前の初期開発段階でした。この時期は、言語仕様や標準ライブラリの設計が固まりつつある過渡期であり、このような基本的な命名規則の適用も進められていました。
`usr/gri/pretty` ディレクトリは、Go言語の初期のパーサーやコンパイラ、AST(抽象構文木)関連のコードが含まれていたと推測されます。このような基盤となるコードにおいて、Go言語の設計原則に沿った命名規則を早期に適用することは、コードベースの一貫性を保ち、将来的な開発の効率性を高める上で非常に重要でした。
したがって、この変更の背景には、Go言語のコアな命名規則をコードベース全体に徹底し、言語の設計思想を反映させるという意図があります。
## 前提知識の解説
### Go言語の命名規則と可視性
Go言語における識別子の可視性(エクスポートされるか否か)は、その識別子の最初の文字のケースによって決まります。
- **エクスポートされた識別子 (Exported Identifiers)**:
- 名前が**大文字**で始まる識別子(例: `Name`, `Age`, `NewObject`, `Compile`)。
- これらは、その識別子が定義されているパッケージの外部からアクセス可能です。他のプログラミング言語における `public` メンバーに相当します。
- 構造体のフィールドがエクスポートされている場合、そのフィールドは他のパッケージから読み書きできます。
- 関数がエクスポートされている場合、その関数は他のパッケージから呼び出すことができます。
- **エクスポートされない識別子 (Unexported Identifiers)**:
- 名前が**小文字**で始まる識別子(例: `name`, `age`, `newObject`, `compile`)。
- これらは、その識別子が定義されているパッケージの内部からのみアクセス可能です。他のプログラミング言語における `private` または `internal` メンバーに相当します。
- 構造体のフィールドがエクスポートされない場合、そのフィールドは同じパッケージ内からのみアクセスでき、外部からは直接アクセスできません。
このシンプルながら強力なメカニズムは、Go言語のAPI設計において重要な役割を果たします。開発者は、識別子の命名だけでその可視性を明確に判断でき、不必要な内部実装の詳細を外部に公開することを防ぐことができます。
### 構造体 (Struct)
Go言語における構造体は、異なる型のフィールド(データ)をまとめるためのユーザー定義型です。C言語の `struct` やJava/C++のクラスのデータ部分に似ています。
```go
type Person struct {
Name string // エクスポートされたフィールド
age int // エクスポートされないフィールド
}
上記の例では、Name
フィールドは大文字で始まるためエクスポートされ、age
フィールドは小文字で始まるためエクスポートされません。
AST (Abstract Syntax Tree)
AST(抽象構文木)は、ソースコードの抽象的な構文構造を木構造で表現したものです。コンパイラやインタプリタがソースコードを解析する際に中間表現として生成されます。このコミットで変更されている ast.go
ファイルは、Go言語のパーサーが生成するASTのノード定義を含んでいたと考えられます。
Go言語の初期開発
Go言語は、GoogleのRobert Griesemer、Rob Pike、Ken Thompsonによって2007年に設計が開始され、2009年11月に一般公開されました。このコミットは2009年1月のものであり、まさに一般公開に向けて言語仕様や標準ライブラリが整備されている最中の変更です。Robert GriesemerはGo言語の主要な設計者の一人であり、彼のコミットは言語の根幹に関わる変更が多いことを示唆しています。
技術的詳細
このコミットは、Go言語の命名規則、特に構造体フィールドの可視性に関する規則をコードベースに適用するものです。変更内容は非常にシンプルで、特定の構造体フィールドの先頭文字を小文字から大文字に変更し、それに伴いそのフィールドを参照している箇所も同様に大文字に変更しています。
具体的には、以下の構造体フィールドが変更されています。
-
Scope
構造体のparent
フィールド:parent *Scope;
からParent *Scope;
へ変更。Scope
はスコープ(変数の有効範囲)を管理するための構造体であり、parent
は親スコープへのポインタを保持していました。このフィールドがエクスポートされることで、パッケージ外からスコープの階層構造にアクセスできるようになります。これは、デバッグツールやリフレクションなど、言語の内部構造を検査するようなツールを開発する際に有用です。
-
Flags
構造体の複数のフィールド:verbose bool;
からVerbose bool;
sixg bool;
からSixg bool;
deps bool;
からDeps bool;
columns bool;
からColumns bool;
testmode bool;
からTestmode bool;
tokenchan bool;
からTokenchan bool;
naming bool;
からNaming bool;
Flags
構造体は、コンパイラやパーサーの動作を制御するための各種フラグ(オプション)を保持していました。これらのフラグがエクスポートされることで、外部からこれらの設定にアクセスしたり、設定を変更したりすることが可能になります。これは、コマンドラインツールやIDE(統合開発環境)がコンパイラの挙動を制御する際に必要となる機能です。例えば、go build
コマンドのオプションが内部的にこれらのフラグに対応している可能性があります。
これらの変更は、単なる命名規則の統一だけでなく、Go言語のAPI設計における「何を公開し、何を隠蔽するか」という設計思想を反映しています。これらのフィールドをエクスポートすることで、Go言語のコンパイラやツールチェインの内部構造の一部が、よりプログラム的にアクセス可能になり、拡張性や統合性が向上します。
コアとなるコードの変更箇所
このコミットでは、以下の4つのファイルが変更されています。
-
usr/gri/pretty/ast.go
:Scope
構造体のparent
フィールドがParent
に変更され、それに伴い参照箇所も修正。scope.parent = parent;
->scope.Parent = parent;
scope = scope.parent;
->scope = scope.Parent;
-
usr/gri/pretty/compilation.go
:Flags
構造体の全てのブール型フィールド(verbose
,sixg
,deps
,columns
,testmode
,tokenchan
,naming
)が、それぞれ先頭大文字のVerbose
,Sixg
,Deps
,Columns
,Testmode
,Tokenchan
,Naming
に変更。- これらのフィールドを参照している箇所も全て修正。
flags.columns
->flags.Columns
flags.testmode
->flags.Testmode
flags.tokenchan
->flags.Tokenchan
flags.verbose
->flags.Verbose
flags.sixg
->flags.Sixg
flags.deps
->flags.Deps
flags.naming
->flags.Naming
-
usr/gri/pretty/parser.go
:P.top_scope.parent
の参照がP.top_scope.Parent
に変更。
-
usr/gri/pretty/pretty.go
:Flag.BoolVar
の呼び出しにおいて、flags
構造体のフィールド名が小文字から大文字に変更。flags.naming
やflags.testmode
の参照がflags.Naming
やflags.Testmode
に変更。
コアとなるコードの解説
変更されたコードは、Go言語の初期のコンパイラ/ツールチェインの一部である pretty
パッケージ内の構造体定義とその使用箇所です。
usr/gri/pretty/ast.go
の変更
Scope
構造体は、Goプログラムのシンボル解決(変数や関数の名前がどの定義に対応するかを決定するプロセス)において重要な役割を果たすスコープの概念を表現しています。
parent *Scope
フィールドは、現在のスコープがネストされている場合に、その親スコープへの参照を保持していました。このフィールドが Parent *Scope
と大文字で始まるように変更されたことで、Scope
構造体のインスタンスが他のパッケージからアクセスされた際に、その親スコープの情報も参照できるようになりました。これは、デバッガやコード分析ツールがプログラムの実行コンテキストやシンボルテーブルを検査する際に役立ちます。
usr/gri/pretty/compilation.go
および usr/gri/pretty/pretty.go
の変更
Flags
構造体は、コンパイルや解析のプロセスにおける様々なオプションや設定をカプセル化しています。例えば、verbose
は詳細なログ出力を有効にするか、testmode
はテストモードを有効にするか、といったブール値のフラグです。
これらのフィールドが全て大文字で始まるように変更されたことで、Flags
構造体のインスタンスが他のパッケージに渡された際に、これらの設定値を外部から読み書きできるようになりました。これは、Go言語のコンパイラやツールチェインが、コマンドライン引数や設定ファイルを通じて外部から設定を注入されることを可能にするための変更です。例えば、go build -v
のようなコマンドは、内部的に Flags.Verbose
を true
に設定している可能性があります。
usr/gri/pretty/parser.go
の変更
Parser
構造体は、Goソースコードを解析してASTを構築する役割を担っています。P.top_scope
は現在のトップレベルスコープを指し、その parent
フィールドを通じてスコープの階層を辿っていました。この参照が P.top_scope.Parent
に変更されたのは、Scope
構造体内のフィールド名変更に合わせたものです。これにより、パーサーがスコープの出入りを管理するロジックが、Go言語の命名規則に準拠する形になりました。
全体として、これらの変更はGo言語の初期段階におけるコードベースの「クリーンアップ」と「標準化」の一環であり、言語の設計原則である「可視性は命名規則によって決定される」というルールを徹底するためのものです。これにより、Go言語のコードベースはより一貫性があり、将来的な拡張やメンテナンスが容易になる基盤が築かれました。
関連リンク
- Go言語の公式ドキュメント(命名規則に関するセクション): https://go.dev/doc/effective_go#names
- Go言語の構造体に関する公式ドキュメント: https://go.dev/tour/basics/18
参考にした情報源リンク
- Go言語の命名規則に関するStack Overflowの議論: https://stackoverflow.com/questions/10631579/go-language-naming-conventions-exported-fields
- Go言語の構造体フィールドの可視性に関する記事: https://medium.com/@ardeshir/go-struct-field-visibility-a-simple-guide-3212c221222
- Robert GriesemerのWikipediaページ: https://en.wikipedia.org/wiki/Robert_Griesemer