[インデックス 1695] ファイルの概要
このコミットは、Go言語の初期のコミットの一つであり、src/lib/http/triv.go ファイルに新しい機能を追加しています。具体的には、HTTPサーバーのデモンストレーション用ファイルである triv.go に、コマンドライン引数とフラグの情報をHTTP経由で表示する機能が追加されました。これにより、Goの flag パッケージと sys.Args (現在の os.Args) の基本的な使用方法をHTTPサービスとして確認できるようになっています。
コミット
commit 03d6909ff74d9793b98f587717d5dbd76a4589d5
Author: Rob Pike <r@golang.org>
Date: Tue Feb 17 19:35:01 2009 -0800
more fun with triv.go: flags and arguments
R=rsc
DELTA=23 (23 added, 0 deleted, 0 changed)
OCL=25088
CL=25134
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/03d6909ff74d9793b98f587717d5dbd76a4589d5
元コミット内容
more fun with triv.go: flags and arguments
R=rsc
DELTA=23 (23 added, 0 deleted, 0 changed)
OCL=25088
CL=25134
このコミットメッセージは非常に簡潔で、「triv.go でフラグと引数をもっと楽しく」という意図が示されています。これは、triv.go がGo言語の初期段階におけるHTTPサーバーの機能テストやデモンストレーションに使われていたことを示唆しています。
変更の背景
このコミットが行われた2009年2月は、Go言語がまだ一般に公開される前の開発初期段階でした。Go言語の設計思想の一つに、シンプルさと実用性があります。コマンドライン引数とフラグの処理は、多くのCLIツールやサーバーアプリケーションにとって基本的な機能です。
triv.go は、Goの標準ライブラリである net/http パッケージの機能を試すための「おもちゃ」のようなファイルだったと考えられます。このコミットの背景には、Go言語の flag パッケージ(コマンドラインフラグの解析)と sys.Args (現在の os.Args、コマンドライン引数へのアクセス) の基本的な動作を、HTTPサーバーという形で視覚的に確認できるようにするという目的があったと推測されます。これにより、開発者はGoプログラムがどのようにコマンドライン引数やフラグを処理するかを、Webブラウザを通じて簡単に検証できるようになりました。
前提知識の解説
Go言語の初期開発と標準ライブラリ
Go言語は、GoogleでRob Pike、Ken Thompson、Robert Griesemerによって設計され、2009年11月に一般公開されました。このコミットは公開前の開発段階のものであり、当時のGo言語のAPIやパッケージ構成は現在とは異なる部分があります。特に、sys パッケージは後に os パッケージに統合されました。
net/http パッケージ
Go言語の net/http パッケージは、HTTPクライアントとサーバーを実装するための強力な機能を提供します。このパッケージを使用することで、Webサーバーを簡単に構築し、HTTPリクエストを処理することができます。
http.Handle(pattern string, handler Handler): 指定されたパターン(URLパス)に対して、http.Handlerインターフェースを実装するハンドラを登録します。http.HandlerFunc(f func(ResponseWriter, *Request)): 関数をhttp.Handlerインターフェースに適合させるためのアダプターです。これにより、通常の関数をHTTPハンドラとして登録できます。http.ListenAndServe(addr string, handler Handler): 指定されたアドレスでHTTPサーバーを起動し、リクエストを待ち受けます。handlerがnilの場合、http.DefaultServeMuxが使用されます。
flag パッケージ
Go言語の flag パッケージは、コマンドラインフラグ(例: -port=8080 や --verbose)を解析するための機能を提供します。
flag.Bool(name string, value bool, usage string) *bool: 真偽値のフラグを定義します。flag.Parse(): コマンドライン引数を解析し、定義されたフラグに値を設定します。flag.VisitAll(fn func(*Flag)): 定義されているすべてのフラグに対して、指定された関数fnを呼び出します。これにより、すべてのフラグの名前、値、デフォルト値などを列挙できます。flag.Flag構造体: 個々のフラグの情報を保持する構造体で、Name(フラグ名)、Value(現在の値)、DefValue(デフォルト値) などのフィールドを持ちます。
sys.Args (現在の os.Args)
Go言語のプログラムが実行される際に渡されるコマンドライン引数は、os パッケージの os.Args 変数を通じてアクセスできます。これは文字列のスライス([]string)であり、最初の要素 (os.Args[0]) は実行されるプログラムのパスです。このコミット当時は sys.Args という名前でしたが、機能は同じです。
技術的詳細
このコミットは、triv.go という既存のHTTPサーバーのデモンストレーションファイルに、以下の2つの新しいHTTPハンドラを追加しています。
-
/flags/エンドポイント (FlagServer関数):- このハンドラは、Goプログラムに定義されているすべてのコマンドラインフラグの情報を表示します。
flag.Bool("boolean", true, "another flag for testing")を使って、booleanflagという名前の真偽値フラグを定義しています。デフォルト値はtrueです。flag.VisitAll関数を使用して、登録されているすべてのフラグをイテレートします。- 各フラグについて、現在の値がデフォルト値と異なる場合は、その旨を明示して表示します。これにより、ユーザーがコマンドラインでフラグの値を変更した場合に、その変更が反映されていることを確認できます。
- HTTPレスポンスの
Content-Typeヘッダをtext/plain; charset=utf-8に設定し、プレーンテキストとして表示されるようにしています。
-
/args/エンドポイント (ArgServer関数):- このハンドラは、Goプログラムが起動された際に渡されたすべてのコマンドライン引数を表示します。
sys.Args(現在のos.Args) をループで処理し、各引数をスペース区切りでHTTPレスポンスとして出力します。- これにより、プログラムがどのような引数で起動されたかをWebブラウザから確認できます。
これらの機能は、Go言語の flag パッケージと sys.Args の基本的な動作を、HTTPサーバーという形で「可視化」する役割を果たしています。開発者は、triv.go を実行し、Webブラウザで /flags/ や /args/ にアクセスすることで、コマンドライン引数やフラグの処理がどのように行われるかを簡単にテスト・確認できるようになります。
コアとなるコードの変更箇所
--- a/src/lib/http/triv.go
+++ b/src/lib/http/triv.go
@@ -45,6 +45,27 @@ func FileServer(c *http.Conn, req *http.Request) {
fmt.Fprintf(c, "[%d bytes]\n", n);
}
+// simple flag server
+var booleanflag = flag.Bool("boolean", true, "another flag for testing")
+func FlagServer(c *http.Conn, req *http.Request) {
+ c.SetHeader("content-type", "text/plain; charset=utf-8");
+ fmt.Fprint(c, "Flags:\n");
+ flag.VisitAll(func (f *flag.Flag) {
+ if f.Value.String() != f.DefValue {
+ fmt.Fprintf(c, "%s = %s [default = %s]\n", f.Name, f.Value.String(), f.DefValue);
+ } else {
+ fmt.Fprintf(c, "%s = %s\n", f.Name, f.Value.String());
+ }
+ });
+}
+
+// simple argument server
+func ArgServer(c *http.Conn, req *http.Request) {
+ for i, s := range sys.Args {
+ fmt.Fprint(c, s, " ");
+ }
+}
+
// a channel (just for the fun of it)
type Chan chan int
@@ -66,6 +87,8 @@ func main() {
flag.Parse();
http.Handle("/counter", new(Counter));
http.Handle("/go/", http.HandlerFunc(FileServer));
+ http.Handle("/flags/", http.HandlerFunc(FlagServer));
+ http.Handle("/args/", http.HandlerFunc(ArgServer));
http.Handle("/go/hello", http.HandlerFunc(HelloServer));
http.Handle("/chan", ChanCreate());
err := http.ListenAndServe(":12345", nil);
コアとなるコードの解説
var booleanflag = flag.Bool("boolean", true, "another flag for testing")
flag.Boolは、コマンドラインフラグを定義するための関数です。"boolean"はフラグの名前です。コマンドラインで-booleanまたは--booleanとして指定されます。trueはこのフラグのデフォルト値です。"another flag for testing"はフラグの簡単な説明(usage message)です。- この行により、
booleanflagという名前の*bool型の変数が宣言され、プログラム内でこのフラグの値にアクセスできるようになります。
func FlagServer(c *http.Conn, req *http.Request)
- この関数は
/flags/パスへのHTTPリクエストを処理します。 c.SetHeader("content-type", "text/plain; charset=utf-8")は、レスポンスがプレーンテキストであることをブラウザに伝えます。fmt.Fprint(c, "Flags:\n")は、レスポンスの冒頭に "Flags:" という見出しを出力します。flag.VisitAll(func (f *flag.Flag) { ... })は、プログラム内で定義されているすべてのフラグを列挙し、それぞれのフラグに対して匿名関数を実行します。- 匿名関数内では、
f.Value.String()でフラグの現在の値を取得し、f.DefValueでデフォルト値を取得します。 if f.Value.String() != f.DefValueの条件により、現在の値がデフォルト値から変更されている場合に、その旨を[default = %s]の形式で明示的に表示します。これにより、ユーザーがコマンドラインで指定した値が正しく反映されているかを確認できます。
- 匿名関数内では、
func ArgServer(c *http.Conn, req *http.Request)
- この関数は
/args/パスへのHTTPリクエストを処理します。 for i, s := range sys.Argsは、sys.Args(現在のos.Args) の各要素(コマンドライン引数)をループで処理します。fmt.Fprint(c, s, " ")は、各引数をスペース区切りでHTTPレスポンスに出力します。これにより、プログラムがどのようなコマンドライン引数で起動されたかをWebブラウザから確認できます。
http.Handle("/flags/", http.HandlerFunc(FlagServer));
http.Handle("/args/", http.HandlerFunc(ArgServer));
main関数内で、新しく定義されたFlagServerとArgServer関数が、それぞれ/flags/と/args/というURLパスにHTTPハンドラとして登録されています。http.HandlerFuncは、通常の関数をhttp.Handlerインターフェースに適合させるためのアダプターです。
これらの変更により、triv.go を実行し、Webブラウザで http://localhost:12345/flags/ や http://localhost:12345/args/ にアクセスすることで、Goプログラムのコマンドライン引数とフラグの処理状況をリアルタイムで確認できるようになりました。
関連リンク
- Go言語の
flagパッケージ: https://pkg.go.dev/flag - Go言語の
osパッケージ (特にos.Args): https://pkg.go.dev/os - Go言語の
net/httpパッケージ: https://pkg.go.dev/net/http
参考にした情報源リンク
- Go言語の公式ドキュメント (現在のバージョン): https://go.dev/doc/
- Go言語の初期のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go言語の
sysパッケージに関する情報 (歴史的経緯): https://go.dev/doc/go1.1#sys (Go 1.1のリリースノートでsysパッケージがosパッケージに統合されたことが言及されています) - Go言語の
flagパッケージの基本的な使い方に関するチュートリアルやブログ記事 (一般的な知識として) - Go言語の
net/httpパッケージの基本的な使い方に関するチュートリアルやブログ記事 (一般的な知識として) - Rob PikeのGo言語に関する講演や記事 (Go言語の設計思想を理解するため)
- Go言語の初期のソースコードを直接参照し、当時の文脈を理解するための情報# [インデックス 1695] ファイルの概要
このコミットは、Go言語の初期のコミットの一つであり、src/lib/http/triv.go ファイルに新しい機能を追加しています。具体的には、HTTPサーバーのデモンストレーション用ファイルである triv.go に、コマンドライン引数とフラグの情報をHTTP経由で表示する機能が追加されました。これにより、Goの flag パッケージと sys.Args (現在の os.Args) の基本的な使用方法をHTTPサービスとして確認できるようになっています。
コミット
commit 03d6909ff74d9793b98f587717d5dbd76a4589d5
Author: Rob Pike <r@golang.org>
Date: Tue Feb 17 19:35:01 2009 -0800
more fun with triv.go: flags and arguments
R=rsc
DELTA=23 (23 added, 0 deleted, 0 changed)
OCL=25088
CL=25134
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/03d6909ff74d9793b98f587717d5dbd76a4589d5
元コミット内容
more fun with triv.go: flags and arguments
R=rsc
DELTA=23 (23 added, 0 deleted, 0 changed)
OCL=25088
CL=25134
このコミットメッセージは非常に簡潔で、「triv.go でフラグと引数をもっと楽しく」という意図が示されています。これは、triv.go がGo言語の初期段階におけるHTTPサーバーの機能テストやデモンストレーションに使われていたことを示唆しています。
変更の背景
このコミットが行われた2009年2月は、Go言語がまだ一般に公開される前の開発初期段階でした。Go言語の設計思想の一つに、シンプルさと実用性があります。コマンドライン引数とフラグの処理は、多くのCLIツールやサーバーアプリケーションにとって基本的な機能です。
triv.go は、Goの標準ライブラリである net/http パッケージの機能を試すための「おもちゃ」のようなファイルだったと考えられます。このコミットの背景には、Go言語の flag パッケージ(コマンドラインフラグの解析)と sys.Args (現在の os.Args、コマンドライン引数へのアクセス) の基本的な動作を、HTTPサーバーという形で視覚的に確認できるようにするという目的があったと推測されます。これにより、開発者はGoプログラムがどのようにコマンドライン引数やフラグを処理するかを、Webブラウザを通じて簡単に検証できるようになりました。
前提知識の解説
Go言語の初期開発と標準ライブラリ
Go言語は、GoogleでRob Pike、Ken Thompson、Robert Griesemerによって設計され、2009年11月に一般公開されました。このコミットは公開前の開発段階のものであり、当時のGo言語のAPIやパッケージ構成は現在とは異なる部分があります。特に、sys パッケージは後に os パッケージに統合されました。
net/http パッケージ
Go言語の net/http パッケージは、HTTPクライアントとサーバーを実装するための強力な機能を提供します。このパッケージを使用することで、Webサーバーを簡単に構築し、HTTPリクエストを処理することができます。
http.Handle(pattern string, handler Handler): 指定されたパターン(URLパス)に対して、http.Handlerインターフェースを実装するハンドラを登録します。http.HandlerFunc(f func(ResponseWriter, *Request)): 関数をhttp.Handlerインターフェースに適合させるためのアダプターです。これにより、通常の関数をHTTPハンドラとして登録できます。http.ListenAndServe(addr string, handler Handler): 指定されたアドレスでHTTPサーバーを起動し、リクエストを待ち受けます。handlerがnilの場合、http.DefaultServeMuxが使用されます。
flag パッケージ
Go言語の flag パッケージは、コマンドラインフラグ(例: -port=8080 や --verbose)を解析するための機能を提供します。
flag.Bool(name string, value bool, usage string) *bool: 真偽値のフラグを定義します。flag.Parse(): コマンドライン引数を解析し、定義されたフラグに値を設定します。flag.VisitAll(fn func(*Flag)): 定義されているすべてのフラグに対して、指定された関数fnを呼び出します。これにより、すべてのフラグの名前、値、デフォルト値などを列挙できます。flag.Flag構造体: 個々のフラグの情報を保持する構造体で、Name(フラグ名)、Value(現在の値)、DefValue(デフォルト値) などのフィールドを持ちます。
sys.Args (現在の os.Args)
Go言語のプログラムが実行される際に渡されるコマンドライン引数は、os パッケージの os.Args 変数を通じてアクセスできます。これは文字列のスライス([]string)であり、最初の要素 (os.Args[0]) は実行されるプログラムのパスです。このコミット当時は sys.Args という名前でしたが、機能は同じです。
技術的詳細
このコミットは、triv.go という既存のHTTPサーバーのデモンストレーションファイルに、以下の2つの新しいHTTPハンドラを追加しています。
-
/flags/エンドポイント (FlagServer関数):- このハンドラは、Goプログラムに定義されているすべてのコマンドラインフラグの情報を表示します。
flag.Bool("boolean", true, "another flag for testing")を使って、booleanflagという名前の真偽値フラグを定義しています。デフォルト値はtrueです。flag.VisitAll関数を使用して、登録されているすべてのフラグをイテレートします。- 各フラグについて、現在の値がデフォルト値と異なる場合は、その旨を明示して表示します。これにより、ユーザーがコマンドラインでフラグの値を変更した場合に、その変更が反映されていることを確認できます。
- HTTPレスポンスの
Content-Typeヘッダをtext/plain; charset=utf-8に設定し、プレーンテキストとして表示されるようにしています。
-
/args/エンドポイント (ArgServer関数):- このハンドラは、Goプログラムが起動された際に渡されたすべてのコマンドライン引数を表示します。
sys.Args(現在のos.Args) をループで処理し、各引数をスペース区切りでHTTPレスポンスとして出力します。- これにより、プログラムがどのような引数で起動されたかをWebブラウザから確認できます。
これらの機能は、Go言語の flag パッケージと sys.Args の基本的な動作を、HTTPサーバーという形で「可視化」する役割を果たしています。開発者は、triv.go を実行し、Webブラウザで /flags/ や /args/ にアクセスすることで、コマンドライン引数やフラグの処理がどのように行われるかを簡単にテスト・確認できるようになります。
コアとなるコードの変更箇所
--- a/src/lib/http/triv.go
+++ b/src/lib/http/triv.go
@@ -45,6 +45,27 @@ func FileServer(c *http.Conn, req *http.Request) {
fmt.Fprintf(c, "[%d bytes]\n", n);
}
+// simple flag server
+var booleanflag = flag.Bool("boolean", true, "another flag for testing")
+func FlagServer(c *http.Conn, req *http.Request) {
+ c.SetHeader("content-type", "text/plain; charset=utf-8");
+ fmt.Fprint(c, "Flags:\n");
+ flag.VisitAll(func (f *flag.Flag) {
+ if f.Value.String() != f.DefValue {
+ fmt.Fprintf(c, "%s = %s [default = %s]\n", f.Name, f.Value.String(), f.DefValue);
+ } else {
+ fmt.Fprintf(c, "%s = %s\n", f.Name, f.Value.String());
+ }
+ });
+}
+
+// simple argument server
+func ArgServer(c *http.Conn, req *http.Request) {
+ for i, s := range sys.Args {
+ fmt.Fprint(c, s, " ");
+ }
+}
+
// a channel (just for the fun of it)
type Chan chan int
@@ -66,6 +87,8 @@ func main() {
flag.Parse();
http.Handle("/counter", new(Counter));
http.Handle("/go/", http.HandlerFunc(FileServer));
+ http.Handle("/flags/", http.HandlerFunc(FlagServer));
+ http.Handle("/args/", http.HandlerFunc(ArgServer));
http.Handle("/go/hello", http.HandlerFunc(HelloServer));
http.Handle("/chan", ChanCreate());
err := http.ListenAndServe(":12345", nil);
コアとなるコードの解説
var booleanflag = flag.Bool("boolean", true, "another flag for testing")
flag.Boolは、コマンドラインフラグを定義するための関数です。"boolean"はフラグの名前です。コマンドラインで-booleanまたは--booleanとして指定されます。trueはこのフラグのデフォルト値です。"another flag for testing"はフラグの簡単な説明(usage message)です。- この行により、
booleanflagという名前の*bool型の変数が宣言され、プログラム内でこのフラグの値にアクセスできるようになります。
func FlagServer(c *http.Conn, req *http.Request)
- この関数は
/flags/パスへのHTTPリクエストを処理します。 c.SetHeader("content-type", "text/plain; charset=utf-8")は、レスポンスがプレーンテキストであることをブラウザに伝えます。fmt.Fprint(c, "Flags:\n")は、レスポンスの冒頭に "Flags:" という見出しを出力します。flag.VisitAll(func (f *flag.Flag) { ... })は、プログラム内で定義されているすべてのフラグを列挙し、それぞれのフラグに対して匿名関数を実行します。- 匿名関数内では、
f.Value.String()でフラグの現在の値を取得し、f.DefValueでデフォルト値を取得します。 if f.Value.String() != f.DefValueの条件により、現在の値がデフォルト値から変更されている場合に、その旨を[default = %s]の形式で明示的に表示します。これにより、ユーザーがコマンドラインで指定した値が正しく反映されているかを確認できます。
- 匿名関数内では、
func ArgServer(c *http.Conn, req *http.Request)
- この関数は
/args/パスへのHTTPリクエストを処理します。 for i, s := range sys.Argsは、sys.Args(現在のos.Args) の各要素(コマンドライン引数)をループで処理します。fmt.Fprint(c, s, " ")は、各引数をスペース区切りでHTTPレスポンスに出力します。これにより、プログラムがどのようなコマンドライン引数で起動されたかをWebブラウザから確認できます。
http.Handle("/flags/", http.HandlerFunc(FlagServer));
http.Handle("/args/", http.HandlerFunc(ArgServer));
main関数内で、新しく定義されたFlagServerとArgServer関数が、それぞれ/flags/と/args/というURLパスにHTTPハンドラとして登録されています。http.HandlerFuncは、通常の関数をhttp.Handlerインターフェースに適合させるためのアダプターです。
これらの変更により、triv.go を実行し、Webブラウザで http://localhost:12345/flags/ や http://localhost:12345/args/ にアクセスすることで、Goプログラムのコマンドライン引数とフラグの処理状況をリアルタイムで確認できるようになりました。
関連リンク
- Go言語の
flagパッケージ: https://pkg.go.dev/flag - Go言語の
osパッケージ (特にos.Args): https://pkg.go.dev/os - Go言語の
net/httpパッケージ: https://pkg.go.dev/net/http
参考にした情報源リンク
- Go言語の公式ドキュメント (現在のバージョン): https://go.dev/doc/
- Go言語の初期のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go言語の
sysパッケージに関する情報 (歴史的経緯): https://go.dev/doc/go1.1#sys (Go 1.1のリリースノートでsysパッケージがosパッケージに統合されたことが言及されています) - Go言語の
flagパッケージの基本的な使い方に関するチュートリアルやブログ記事 (一般的な知識として) - Go言語の
net/httpパッケージの基本的な使い方に関するチュートリアルやブログ記事 (一般的な知識として) - Rob PikeのGo言語に関する講演や記事 (Go言語の設計思想を理解するため)
- Go言語の初期のソースコードを直接参照し、当時の文脈を理解するための情報