[インデックス 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.