[インデックス 10284] ファイルの概要
コミット
このコミットは、Go言語の標準ライブラリにおけるos
パッケージとsyscall
パッケージのPlan 9ビルドに関する修正です。具体的には、エラーハンドリングのAPI変更(error
パッケージからerrors
パッケージへの移行、およびError()
メソッドの標準化)に対応し、Plan 9環境でのビルドが正しく行われるようにするための調整が含まれています。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/cabe0e6ad38b1498098c7d9aba70dc218b0a23a7
元コミット内容
os, syscall: fix Plan 9 build
R=rsc
CC=golang-dev
https://golang.org/cl/5330067
変更の背景
このコミットが行われた2011年11月頃のGo言語は、まだ開発の初期段階にあり、APIの変更が頻繁に行われていました。特に、エラーハンドリングのメカニズムは進化の途中にありました。初期のGoでは、エラーを表すためにerror
という名前のパッケージが存在し、その中にString()
メソッドを持つインターフェースが定義されていました。しかし、Go言語の設計思想が固まるにつれて、よりシンプルで統一されたエラーハンドリングの仕組みが求められるようになりました。
その結果、error
パッケージは非推奨となり、Goの組み込み型であるerror
インターフェース(Error() string
メソッドを持つ)が標準的なエラー表現として確立されました。また、汎用的なエラーを生成するためのerrors
パッケージが導入されました。
このコミットは、このようなGo言語内部のエラーハンドリングAPIの変更に、Plan 9向けのコードが追従していなかったために発生したビルドエラーを修正するものです。Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、Go言語は初期からPlan 9を含む複数のOSをサポートしていました。そのため、OS固有のコードもGo言語のAPI変更に合わせて更新する必要がありました。
前提知識の解説
Plan 9 from Bell Labs
Plan 9は、ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、すべてのリソース(ファイル、デバイス、ネットワーク接続など)をファイルシステムとして表現するというユニークな設計思想を持っています。Go言語の開発者の一部はPlan 9の開発にも携わっており、Go言語の設計思想にもPlan 9の影響が見られます。このコミットでは、Go言語がPlan 9環境で動作するためのOS固有のコードが修正対象となっています。
Go言語のerror
インターフェース
Go言語におけるエラーハンドリングの基本は、組み込みのerror
インターフェースです。このインターフェースは非常にシンプルで、以下のように定義されています。
type error interface {
Error() string
}
つまり、Error() string
メソッドを持つ任意の型はerror
インターフェースを満たします。これにより、Goの関数はエラーが発生した場合にこのerror
インターフェース型の値を返すことで、呼び出し元にエラー情報を伝達します。
String()
メソッドとError()
メソッドの変遷
Go言語の初期のバージョンでは、エラーインターフェースのメソッド名がString()
であった時期がありました。しかし、標準ライブラリ全体でエラーを表現する際に一貫性を持たせるため、そしてfmt.Stringer
インターフェース(String() string
を持つ)との混同を避けるために、エラーインターフェースのメソッド名はError()
に変更されました。このコミットは、この変更にPlan 9固有のコードが対応していなかった部分を修正しています。
syscall
パッケージ
syscall
パッケージは、Goプログラムから基盤となるオペレーティングシステムのシステムコールを直接呼び出すための機能を提供します。OS固有の低レベルな操作(ファイルI/O、プロセス管理、ネットワーク通信など)を行う際に使用されます。このコミットでは、Plan 9のシステムコールに関連するエラーハンドリングの修正が含まれています。
errors
パッケージ
Go 1.0以降、標準ライブラリにはerrors
パッケージが導入されました。このパッケージは、シンプルな文字列からerror
型の値を生成するためのerrors.New()
関数を提供します。
package errors
func New(text string) error { return &errorString{text} }
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
このコミットでは、以前はカスタムのエラー生成関数や非推奨のerror
パッケージを使用していた箇所が、errors.New()
に置き換えられています。
技術的詳細
このコミットは、主に以下の2つの技術的な変更を含んでいます。
-
error
パッケージからerrors
パッケージへの移行:src/pkg/os/env_plan9.go
とsrc/pkg/os/exec_plan9.go
において、以前は"error"
パッケージをインポートしてエラーを扱っていましたが、これをGoの標準的な"errors"
パッケージに切り替えています。これは、Go言語のエラーハンドリングのAPIが成熟し、errors
パッケージが標準的なエラー生成メカニズムとして確立されたことによるものです。 -
String()
メソッドからError()
メソッドへの変更:src/pkg/os/error_plan9.go
では、NewSyscallError
関数内でsyscall.Error
型のString()
メソッドを呼び出していた箇所がError()
メソッドの呼び出しに修正されています。これは、syscall.Error
インターフェースがString()
ではなくError()
を実装するように変更されたためです。src/pkg/syscall/syscall_plan9.go
では、syscall.Error
インターフェースの定義自体がString() string
からError()
に変更されています。また、ErrorString
型もString()
メソッドではなくError()
メソッドを実装するように修正されています。これにより、syscall
パッケージ内のエラー型がGo言語の標準error
インターフェースの定義に完全に準拠するようになりました。
これらの変更は、Go言語全体のエラーハンドリングの一貫性を保ち、Plan 9環境でのビルドと実行を保証するために不可欠でした。
コアとなるコードの変更箇所
src/pkg/os/env_plan9.go
--- a/src/pkg/os/env_plan9.go
+++ b/src/pkg/os/env_plan9.go
@@ -7,7 +7,7 @@
package os
import (
- "error"
+ "errors"
"syscall"
)
src/pkg/os/error_plan9.go
--- a/src/pkg/os/error_plan9.go
+++ b/src/pkg/os/error_plan9.go
@@ -28,7 +28,7 @@ func NewSyscallError(syscall string, err syscall.Error) error {
if err == nil {
return nil
}
- return &SyscallError{syscall, err.String()}
+ return &SyscallError{syscall, err.Error()}
}
var (
src/pkg/os/exec_plan9.go
--- a/src/pkg/os/exec_plan9.go
+++ b/src/pkg/os/exec_plan9.go
@@ -5,6 +5,7 @@
package os
import (
+ "errors"
"runtime"
"syscall"
)
@@ -47,7 +48,7 @@ func (note Plan9Note) String() string {
func (p *Process) Signal(sig Signal) error {
if p.done {
- return NewError("os: process already finished")
+ return errors.New("os: process already finished")
}
f, e := OpenFile("/proc/"+itoa(p.Pid)+"/note", O_WRONLY, 0)
src/pkg/syscall/syscall_plan9.go
--- a/src/pkg/syscall/syscall_plan9.go
+++ b/src/pkg/syscall/syscall_plan9.go
@@ -19,13 +19,13 @@ const ImplementsGetwd = true
// An Error can represent any printable error condition.
type Error interface {
- String() string
+ error
}
// ErrorString implements Error's String method by returning itself.
type ErrorString string
-func (e ErrorString) String() string { return string(e) }
+func (e ErrorString) Error() string { return string(e) }
// NewError converts s to an ErrorString, which satisfies the Error interface.
func NewError(s string) Error { return ErrorString(s) }
コアとなるコードの解説
src/pkg/os/env_plan9.go
および src/pkg/os/exec_plan9.go
の import
変更
これらのファイルでは、import "error"
がimport "errors"
に変更されています。これは、Go言語の標準エラーパッケージがerror
からerrors
に移行したことを反映しています。errors
パッケージは、errors.New("some error message")
のように、シンプルな文字列からerror
インターフェースを満たすエラー値を生成するための標準的な方法を提供します。
src/pkg/os/error_plan9.go
の err.String()
から err.Error()
への変更
NewSyscallError
関数内で、err.String()
がerr.Error()
に修正されています。これは、syscall.Error
インターフェースが、Go言語の標準error
インターフェースの定義に合わせて、String()
メソッドではなくError()
メソッドを実装するように変更されたためです。これにより、エラーメッセージの取得方法が統一されます。
src/pkg/os/exec_plan9.go
の NewError
から errors.New
への変更
Process.Signal
メソッド内で、NewError("os: process already finished")
がerrors.New("os: process already finished")
に修正されています。これは、カスタムのエラー生成関数NewError
の代わりに、標準のerrors
パッケージが提供するerrors.New
関数を使用するように変更されたことを示しています。これにより、エラー生成のコードがより標準的で一貫性のあるものになります。
src/pkg/syscall/syscall_plan9.go
の Error
インターフェース定義と ErrorString
のメソッド名変更
このファイルでは、syscall.Error
インターフェースの定義がString() string
からerror
に変更されています。これは、syscall.Error
がGo言語の組み込みerror
インターフェースを直接埋め込む(またはそのように振る舞う)ように変更されたことを意味します。
また、ErrorString
型が実装するメソッドもString() string
からError() string
に変更されています。これにより、syscall
パッケージ内で定義されるエラー型が、Go言語全体で統一されたerror
インターフェースの規約に完全に準拠するようになります。
これらの変更は、Go言語のエラーハンドリングの進化と標準化の過程を示すものであり、特定のOS(この場合はPlan 9)向けのコードもその変更に追従する必要があったことを明確に示しています。
関連リンク
- Go CL 5330067: https://golang.org/cl/5330067
参考にした情報源リンク
- Go言語の
error
インターフェースに関する公式ドキュメントやブログ記事 (具体的なURLはコミット当時の情報ではないため割愛しますが、Go言語のエラーハンドリングの歴史を理解するために参照しました) - Plan 9 from Bell Labsに関する情報 (一般的な知識として参照)
- Go言語の
errors
パッケージに関する公式ドキュメント (一般的な知識として参照) - Go言語の
syscall
パッケージに関する公式ドキュメント (一般的な知識として参照) - Go言語のコミット履歴と関連する議論 (このコミットの背景を理解するために参照)I have generated the detailed technical explanation in Markdown format, following all the specified instructions and chapter structure. I have used the commit information and my knowledge of Go's error handling evolution and Plan 9 to provide a comprehensive explanation.
I believe I have completed the request.