2014年9月27日土曜日

Golang Cafe #48を開催しました。

Golang Cafe #48を開催しました。

今回は、Gunosy.go#10の発表資料が公開されましたので、資料を読み進めました。

読んだ資料は@y_matsuwitterさんの「Go言語におけるテストの基本」と@daimatzさんの「Dependency Injectionからモックライブラリまで」の2つです。

テストの基本についての大体の内容は、Golang Cafeでも触ってきたものだったので、参加者全員が知っているものでした。特徴として、テストコードに与える引数と、期待する戻り値を書いておいて比較するというサンプルコードが見受けられましたが、標準パッケージでも(特にmathあたり)そのような構成になっています。

ここで、話が出たのは、「どこまでテストをするか?」という話。これまでも何度も出てきていることなのですが、その辺を議論し始めるとGoの話ではなく、開発手法の話になってしまうので難しいところです。
それと、「テストを書きながら作る」か「開発した後で作る」かという話もありました。
それ以外にも「TDDする」というようなことも。
後でテストコードを見ることで、仕様や、プログラマの考えていたことがわかるようなテストを書かなくてはいけないということも話しました。

個人的には、「後でデグレを起こさないようにする」ということに主軸を置いているので、境界値のテストを主にやっておけば良いのかな?と考えていたりします。
全てのコードを通すようなテストを書いておくのは良いと思うのですが、
例えば、fmt.Printf()が失敗した後のケース(昔、そういう仕事をしたもので…)のテストが要るか?と言われると、その「PCが壊れてしまっている」状況で何ができるか?を考えたら、そんなに重要とは思えないので、panic()が書かれている事をコードレビューしておけば良いと思われます。

(こういうのを書いてしまうと、炎上すると困るのでこの程度に…)

Dependensy Injectionの方に入ると、やっぱり「Generics欲しい」という話がありました。私はそこまでGenericsを使いこなしていないので、便利さに気がつかないのですが、Javaや、C#をやっている人にはないと辛いようです。

資料の中身としては、通信が必要だったりするアプリケーションなどにはモックを作って擬似的なテストを行わなければいけない時に遭遇する。それをするためにはDIを使って、テストの時と、本番の時で挙動を変えられるようにしておくと便利ということ。
それをGoでやるにはどうするか。ということで、メソッド引数、オブジェクトを渡す、インターフェイスを引数で。という例が紹介されたようです。

私ももう少しこういう話題について勉強しておかないといけないのかな。と思った回でした。

次回は昔やった、結城浩さんの「Java言語によるデザインパターン入門(マルチスレッド編)」のGoに置き換えるというのを再開する予定です。

個人的には開発したいものがあるんだけど今のGolang Cafeでやるのは難しそう…かな。

2014年9月21日日曜日

Golang Cafe #47を開催しました。

Golang Cafe #47を開催しました。前回はかなり脱線してしまったので、blogは省略しました。今回は、GoでWebsocketをさわってみるという内容で、go.netのwebsocketを使ってみました。

go.net/websocketのインストールは、以下のコマンドで行います。

$ go get code.google.com/p/go.net/websocket

サンプルコードはgithubにpushしていますので、そちらをごらん下さい。
使い方は非常に簡単で、単純な折り返しのWebsocketならすぐに作れるようになっています。

package main

import (
 "io"
 "net/http"

 "code.google.com/p/go.net/websocket"
)

func echoHandler(ws *websocket.Conn) {
 io.Copy(ws, ws)
}

func main() {
 http.Handle("/echo", websocket.Handler(echoHandler))
 http.Handle("/", http.FileServer(http.Dir("./gdgchugoku_html5_business/html/011")))
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  panic("ListenAndServe: " + err.Error())
 }
}

githubにも同じものが上がっていますが、転載しました。
Websocketのハンドラ登録は、標準パッケージのhttp.Handle()を使って登録します。
指定するHandlerのオブジェクトでwebsocketパッケージの型を指定するようになっています。

折り返しするだけであれば、io.Copy()で引数のWebsocketのオブジェクトにコピーするだけでいいようになっています。
送信用と受信用の引数があるかと思ったのですが、Websocketの場合はまとまっているようです。

当日、見つけたポイントとしては、Websocketのオブジェクトをずっと使いたい場合は、Handlerの関数を抜けてはいけないということでした。関数を抜けるとsocketがcloseされるので、for {}で無限ループさせる必要があります。

ローカルでのテストしか行っていませんが、レスポンスも早く、サーバ側からの通知などにも利用できるのでWebsocket自体の仕様が固まって、何かに使えればいいなと思いました。

次回は、gunosy.goの資料が公開されているようなので、その資料を読みます。

2014年9月7日日曜日

Golang Cafe #45を開催しました。

Golang Cafe #45を開催しました。

今回も、3人での開催になりました。

内容は、急にqiitaに投稿された記事が気になったので、3人で読み進めてみました。
タイトルが「Goでxxxのポインタを取っているプログラムはだいたい全部間違っている」という、結構攻めた感じのタイトルだったので、食いついてしまいました。

内容としては、ポインタを使うのは良いが「自分が何をしているのか理解していない」のであれば、ポインタを使う意味がないということでした。
少し補足をすると、文字列、interface、channel、Map、sliceは「元からポインタ」なので、ポインタを使うと、「ポインタのポインタ」になってしまって、「直接参照すればいいのに何してるの?」ということになってしまう。ということです。

例えば、Mapだと、 +Takanobu Haginoさんのサンプルコードで確認すると、Mapは引数にポインタを渡さなくても、呼び出し先でMapに値を追加することができ、当然、呼び出し元でも追加されたものは反映されます。(=元からポインタということ)

fmt.Println()で書きだしてみると、channelもアドレスが出力されるのでやっぱりポインタだということがわかります。

従って、ポインタを使う時というのがどういう意図があるのかを明確にして使いましょう。ということでした。

次に、@lestrratさんの資料を読みました。
ここで議論になったのが、「intのバイト数が変わる」ということについて。

昔は、intという型はなく、int8、int16、int32、int64とビット数をつけた型だけがありました。(当然、byteもない。昔はint8と宣言していたけど、いつの間にかbyteを使うようになってしまった。これは大きさが変わらないので大丈夫。)

実際、intは”same size as uint"ということで、(個人的にはint32のaliasだと思っていたけど)uintと同じサイズの整数型という定義になります。
そこで、uintのサイズは何かというと、32bit or 64bitなので、goのコンパイラのビルド時に決まる。ということでしょうね。
(C言語のintと変わらず、どちらになるかわからないということ)

したがって、intのサイズが変わることでハマるよ。ということですから、明確にサイズが影響するなら、int32やint64の変数の型を使うようにするべきだろう。という結論になりました。(と私は理解している)

最後に、 +Takanobu Haginoさんのtextream解析ツールのソースコードを読みました。
非常にシンプルだったので、特に何か言わなければならないというものはなかったように思います。
構成としては、バックエンドでサイトの情報を取得して、フロントはgorillaを使ったWebサーバという構成で作られています。
いろんな便利なライブラリも使われていて、「実戦向き」のプログラムで非常に楽しく読ませていただきました。

最近、qiitaにGoogle Apps Scriptの記事を2個書いてましたが、Goに興味がないわけではなく、必要になった要求を簡単に満たせるのがGASだったということで、要求を満たしやすい言語を選ぶのがいいんだろうと思ったりしています。

次回(後2時間後)は、また最近話題になった記事とかソースコードレビューとか、何か作る時間にしたいと思います。