Go lang始めてみた
A Tour of GoのConcurrency以外を読み終えた。
ここまでの内容をまとめるのにちょうど良さそうなのでyesコマンドを実装してみた。
仕様
- 1つ目のコマンドライン引数が"-h"または"--help"ならばヘルプメッセージを表示
- コマンドライン引数がなければ"y"をひたすら出力
- その他の場合はコマンドライン引数を" "でjoinした文字列をひたすら表示
最適化を頑張らない
コード
yes.go
package main
import (
"fmt"
"io"
"os"
"strings"
)
type yesReader struct{
yes string
reader io.Reader
}
func (r *yesReader) Read(b []byte) (int, error) {
n, err := r.reader.Read(b)
if err != nil {
return n, err
}
for i := range b {
b[i] = byte(r.yes[i])
}
return len(b), nil
}
func isNoCommandlineArgs() bool {
return len(os.Args) == 1
}
func includeHelpCommandlineArg() bool {
return os.Args[1] == "-h" || os.Args[1] == "--help"
}
func execHelp() {
fmt.Println(`Usage: yes String or Option
-h --help: display this message`)
}
func yesOnece(yes string) {
s := strings.NewReader(yes)
r := yesReader{yes, s}
b := make([]byte, len(yes))
for {
_, err := r.Read(b)
fmt.Println(string(b))
if err == io.EOF {
break
}
}
}
func main() {
var yes string
switch {
case isNoCommandlineArgs():
yes = "y"
case includeHelpCommandlineArg():
execHelp()
return
default:
yes = strings.Join(os.Args[1:], " ")
}
for { yesOnece(yes) }
}
実行
$ go run yes.go --help
Usage: yes String or Option
-h --help: display this message
$ go run yes.go foo bar baz | head -n 5
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
signal: broken pipe
$ go run yes.go | head -n 5
y
y
y
y
y
signal: broken pipe
感想
嬉しい。
次はLISPのインタープリタを書いてみたい。