2012年2月19日日曜日

Goの新しいコマンドとパッケージ管理

最近Go言語がVer.1に向けて開発されているようなのですが、
Weekly-2012-02-07辺りからコマンドが変わったみたいなので、
変更されたコマンドを少し使ってみようと思います。

まず最初に、環境変数$GOPATHを定義します。

この$GOPATH変数で指定されたパスに、ビルドしたパッケージのモジュールと、ソースコード、テストコードをひとまとめにして置いておきます。
ちなみに、GOPATHはPATHと同じように複数の場所を指定することも可能なようなので、
ソースコードをまとめる場所は複数作る事もできます。
ただし、go installコマンド(後で実行例を紹介しますが)は指定した最初のパスにモジュールを反映するようなので、注意が必要です。

さて、最初にHello Worldから。以下のソースをhello.goに保存しておきます。

package main

import (
 "fmt"
)

func main() {
 fmt.Printf("Hello World!\n")
}

上記のおなじみのコードを実行するには、以下のコマンドを実行するだけです。
以前は、8g hello.go && 8l -o hello hello.8 && helloみたいな感じでした。

$ go run hello.go

このコマンドを実行すると、コンパイル、リンク、実行まで一気にやってくれます。
多分、無事"Hello World!"が表示されると思います。
ちなみに、

$ go build -o hello hello.go

だと、hello.goと同じディレクトリに実行ファイルが生成されます。
go runコマンドだと実行ファイルは作成されませんでした。
(正確にはファイルが残っていなかった。どうしているんだろう?)

例えば、以下のようにパッケージを含むプログラムを作りたい時。

package main

import (
 "fmt"
 "mymath"
)

func main() {
 fmt.Printf("Hello World!\n")

 fmt.Printf("簡単な計算:1 + 1 = %d\n", mymath.Add(1, 1))
}

パッケージのファイルを$GOPATH変数で指定したパス配下のsrcディレクトリに
格納します。今回の例ではmymath.goというファイルで保存しています。

package mymath

func Add(a, b int) int {
 return a + b
}

保存した後、以下のコマンドを実行すると、パッケージがコンパイルされ、pkgディレクトリに生成されます。GOPATH変数にパスを複数指定している場合は、最初のディレクトリに格納されていると思います。

$ go install mymath

go installコマンドを実行した後、再度、go run hello.goで実行すれば、
簡単な計算もされることと思います。

しかも、Go言語標準のテストパッケージについても簡単に実行できるようになりました。
今回は、パッケージのテストを実行しています。
まず、mymath_test.goというファイルをmymath.goと同じディレクトリに作ります。

package mymath

import "testing"

func TestAdd(t *testing.T) {
 const ans = 2
 if Add(1, 1) != ans {
  t.Errorf("Add(%d, %d) == %d", 1, 1, Add(1, 1))
 }
}

テストパッケージは先頭がTestで始まり、最初が大文字(例:TestXxxみたいな感じ)の必要があるので、関数名はTestAddとしています。
あとは、同じパッケージのメソッドを呼び出し、結果を比較しています。
基本的にNGの条件を記述すれば良いです。
JUnitだと、正しい条件を記述するのですが、GoのTestingは反対なので注意してください。(反対というより、エラーを通知する関数しかないのか。)

プログラムを作成した後は、以下のコマンドで結果を確認します。

$ go test mymath

結果が正しければ、okとだけ出ます。

という感じで、パッケージのテストコードも実行しやすくなりました。

実行結果はこのBlogには載せていませんので、皆さんの環境で実行した結果をみて
検証してみてください。

ちなみに、GAE/GのSDKではまだこの仕組は導入されていませんのでGo言語の
ソースコードをダウンロードしてコンパイルするか、バイナリをダウンロードしてみてください。

注意点としては、私の書籍を購入してGAE/Gのプログラムを動かした方は
SDKのディレクトリにパスを通していると思います。これが、今回は邪魔になるので、
$PATHからSDKのパスを外してから動かしてみてください。