ニコニコ動画の人気動画を配信するtwitter botつくった(Go言語使ってみた)
golang書いてみようとふと思ってみんな大好きTwitter bot作りました。ニコニコ動画の人気動画を配信するという体裁のbotです。
作ったやつ→ニコニコ動画_Fav
ソースは→https://github.com/yfujita/nico-fav-tweet
動作
ニコニコ動画の公開RSSでランキングをXML形式で取れるので、毎時ランキングを定期的に参照して、トップ10で新しいものがあったらツイートしています。Go言語つかってみた
以前Tour of Goはやったことあったものの、すっかり忘れていてゼロからのgolangでした。構造体とかポインタとか出てくるので、C言語書ける人はとっつきやすい印象でした。ちょっと触った程度ですけど、復習のためにここまでやったことをまとめておきます。
①なにはともあれTour of Go
A Tour of Goというgolang入門サイトに実際にコードを動かしながら学べるとても丁寧なチュートリアルがあるので、最初は何も考えずにこれやりました。
②golangのインストール
http://golang.jp/installなどを参考にインストール。
④GOPATHの設定
環境変数GOPATHを設定します。
export GOPATH=/hoge/fuga
go getするとGOPATHにライブラリが格納されて、ビルドする際に自動的にGOPATHを参照して依存ライブラリを解決するみたいです。なので設定が必須。複数のディレクトリが設定が可能で、その場合はgo getした時には最初のpathにライブラリが格納されるらしいです。
⑤Hello World!!!
Hello World!!!
package main import( "fmt" ) func main() { fmt.Println("Hello World!!!") }
という感じのファイルを適当なディレクトリにhello.goという名前で作成して
go run hello.go
で実行できます。かんたん! mainパッケージのmain関数が実行されるみたいです。
⑥ソースファイルを複数に分けたい
package名さえ同じにしておけば複数のファイルに分けてかけます。別ファイルのソースの関数も構造体も自由に参照可能です。
go run *.go
とかで実行出来そう。
⑦オブジェクト指向っぽくしたい
golangにはクラスという型はないですが、構造体にメソッドを定義出来ます。C→Javaの順番でやった人はクラスって構造体にメソッドを定義したものかなという感じで入ると思うのですが、まさにそれなのでクラスよりもこっちのがしっくり来ます!
type Hoge struct { Value int } func (hg *Hoge)showValue() { fmt.Println(hg.Value) }
みたいな感じで定義して
func main() { hg := new(Hoge) hg.Value = 10 hg.showValue() }
みたいな感じでオブジェクト指向。
⑧平行処理したい
golangにはgoroutineというのがあって、chan型と組み合わせて超簡単に平行処理がかけるみたいです。
func main() { ch := make(chan int) go func(ch chan int) { ch <- 1 }(ch) fmt.Println(<-ch) }
これだけ!(たぶん動く気がする)
「go 関数」と書くと関数が別スレッドで実行されるらしいです。
データの受け渡しはchan型を使うのがいいらしい。メモリ共有されてるので直接他スレッドの変数に値を書き込むことが出来るけどあんまりやらない方がいいっぽい。「ch <- 1」で値を格納。「<-ch」で値の取り出し。「<-ch」の時にまだ値が設定されてなかったら、勝手に実行スレッドをロックして値が設定されるのを待ってくれるらしい!便利!
⑨ビルドしたい。
ソースのあるところでgo build します!
⑩どういうディレクトリ構成にしたらいいのかよく分からない
githubのgoのコードとかみてもなんかすっごくシンプルな構成でよくわからない。というかみんなライブラリなんでmain packageがない。
と思っていたら素敵な記事がありまして
SoundCloudではGoをガンガン使っているらしい!ディレクトリ構成についても書いてあって、リポジトリ下にmainパッケージのソースコードをガン置してることが多いらしい。(やっちゃ駄目と書いてある)
⑪パッケージ分けたい
mainパッケージにガン置きやっちゃ駄目となるとディレクトリつくってパッケージを分けるのが良さそうなので、分けてみる。
{project-dir} |-main.go |-sub |-sub.go
こうやっておいてmain.goから「import("sub")」ってやればいけるのかなとも思ったけどsubなんてないって怒られる。
依存ライブラリの解決にはGOPATHを参照しますが、GOPATHにsubなんてないよって言われる。
ってことはこれ毎回GOPATHをカレントに設定してかなきゃいけないのかー詰んだ。
と思っていたら
@meumeu69 普通に import "URL" とかにして、開発時もそもそも gopath の内側でやっておくと特に何もしなくていいので便利っすよ。あと main から分離しておくと godoc とかでマニュアル出しやすかったりとか。
2014-05-10 04:39:22 via web to @meumeu69
{GOPATH} |-bin |-pkg |-src |-{project-dir} |-main.go |-sub |-sub.go
みたいな感じで、main.goからはimport("{project-dir}/sub")とするとsubパッケージがimportできました。この状態で{project-dir}で「go install」するとbinに実行ファイルも作ってくれたりしていたれりつくせりです。
ちなみに、githubにあるgoパッケージをgo getすると「{GOPATH}/src/github.com/userName/repositoryName/packageName」という感じでインストールしてgo installまでしてくれるようで、つまりgithubのリポジトリにはpackageディレクトリだけおいとけばgo get可能ということっぽい!だからgithubにあるgolangのリポジトリはどれもこれもシンプルな構成になっているんですね。すごくいいですね。
⑫githubにうpしたい
git pushです!
githubにあげる予定のある場合は、最初から{GOPATH}/src/github.com/userName/repositoryNameのディレクトリで作業しておくとそのままgithubにうp出来てgo getもしやすくてすごい。
という感じで今のところやったことをまとめました。
継続して何かしたいけど何をしましょう。
このbotでもロギングとかエラー処理とかでまだ遊べそうかもしれないですが。