React.jsのチュートリアルをGoで動かしてみた
React.js入門しました。とりあえず動かしてみたレベル。
(とりあえず触る&ソース読んでよくわからない点とかメモってから、概要とか読む派なので。。。)
チュートリアルのexampleで用意されている言語はRuby, Node.js, Pythonしかありませんが、あえてGoでやります。
Goで起動する
チュートリアルのソースコードをgit clone
で取得します。
$ git clone https://github.com/reactjs/react-tutorial
プロジェクト直下にmain.goを作成します。(goji使ってます)
$ go get github.com/zenazn/goji
React.jsのチュートリアルをGoで書いてみたhttps://github.com/reac ...
あとは起動するだけ。
$ go run main.go
なんかチャットっぽいやつのようだ。
色々触って動きを追って見る
サーバーのログを見るとわかるけど、2秒毎にGET:/comments.json
が呼ばれている。
それっぽいコードがある。
// public/scripts/example.js(126行目) <CommentBox url="comments.json" pollInterval={2000} />,
このCommentBoxのComponentの実装は以下のようにajaxでGETしてsetState
でCommentBoxのrenderを行っている。
// public/scripts/example.js(29行目) var CommentBox = React.createClass({ // 2秒毎に呼ばれるやつ loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, // CommentBox子要素のCommentFormのPostボタンを押した時に呼ばれる handleCommentSubmit: function(comment) { var comments = this.state.data; comments.push(comment); this.setState({data: comments}, function() { // `setState` accepts a callback. To avoid (improbable) race condition, // `we'll send the ajax request right after we optimistically set the new // `state. $.ajax({ url: this.props.url, dataType: 'json', type: 'POST', data: comment, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }); }, // 初期呼び出し getInitialState: function() { return {data: []}; }, // TODO: これが2秒毎にajax呼ぶやつのトリガーっぽい? componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, // 表示更新(setStateで呼ばれる) render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit} /> </div> ); } });
CommentBoxは子要素にCommentListとCommentFormを持っていて、setStatusで渡されたdataでrenderを呼び出している。
また、CommentFormのPostボタンを押したは、親要素からpropsでもらったonCoomentSubmitのfunctionを呼び出して、ajaxでPOST:/comments.json
を呼び出している。
呼び出し後のrenderの流れは2秒毎に呼んでいる方と同じ。
おわり
とりあえず動かしてみて、その後に概要を読んでReact.jsの良さがわかってきた気がする。
英語が苦手な方は、こちらを読むといいと思います!!!とてもわかりやすいです!
GoogleComputeEngineのVMインスタンスにerrbitを構築
はじめに
errbitを業務で使っているので、自分用のSandboxがほしくて作ろうかなと思ってやってみたら、 思った以上に苦戦したので備忘録がてら残します。
※herokuでの導入例はよくあるのですが、ローカルとかAWSとかでの記事があまり見当たらず...
苦戦したのは、たぶん自分がRails初心者なのが理由かと思いますが一応
環境について
※ちなみにf1-micro(vCPU 1 個、メモリ 0.6 GB)はメモリ不足でbundle install
でコケますのでご注意ください。
rubyとかその他必要な物をinstall
色々更新とinstall
$ sudo apt-get update $ sudo apt-get install -y mongodb $ sudo apt-get install -y libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libzip-dev libssl-dev $ sudo apt-get install -y libreadline6 libreadline6-dev $ sudo apt-get install -y g++ $ sudo apt-get install -y make $ sudo apt-get install -y git
rubyのバージョン管理はrbenvにした。
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile $ source .bash_profile
2.1.0だとlibreadlineのバージョンが上がって型の定義が変更な不具合で詰んだので、2.1.2にしました。
$ rbenv install -v 2.1.2
install ながい。。。
$ rbenv rehash $ rbenv global 2.1.2
bundlerとかinstall
$ gem install bundler $ gem install therubyracer
errbit起動
ちなみにinstallしたerrbitのリビジョンはこちら 。更新が活発なのでご注意ください↓
errbit/errbit at d3d7ad54f7b136a804d5cb7c9a118ae35b7e5c7a · GitHub
errbitをgit cloneして手順通り起動。
$ git clone https://github.com/errbit/errbit $ cd errbit $ bundle install $ rake errbit:bootstrap $ sudo script/rails server -p 80
supervisorで常駐させる
無事起動したけど、常駐してほしいので、雑にsupervisorを導入。
$ sudo apt-get install supervisor $ sudo vim /etc/supervisor/conf.d/supervisord.conf
supervisord.conf
[program:errbit] command=sudo /home/kyokomi/.rbenv/shims/ruby /home/kyokomi/errbit/script/rails server -p 80 user=kyokomi autorestart=true stdout_logfile=/var/log/supervisor/jobs/errbit.log stdout_logfile_maxbytes=1MB stdout_logfile_backups=5 stdout_capture_maxbytes=1MB redirect_stderr=true
supervisor起動
sudo service supervisor start
おわり
Goでエラー投げまくってる。
参考
Goのテンプレート言語egoを使ってみた
golangのtext/template最近ようやく慣れてきたけど、
やっぱり{{}}
が増えてくると辛いので、他のパッケージに手をだしてみました。
egoが触った中で一番しっくりきたのと、一通り色々なことができそうな気配を感じたので気に入りました。
インストール
go get
だけでOKです。
$ go get github.com/benbjohnson/ego
egoを呼び出すソースコード
ディレクトリ構成
├── main.go └── templates └── sample.ego
templates/sample.ego
は、ego用のtemplateファイル。拡張子.ego
じゃないとダメです。
egoを実行する
$ ego -package main templates
実行するとego.go
が作成される。*1
├── ego.go ├── main.go └── templates └── sample.ego
go runで実行する
$ go run main.go ego.go ## Titleを表示 test ## Titleをローカル変数titleに代入して表示 title = test ## FooListをfor文で回して表示 abc ローカル変数のスコープ = test def ローカル変数のスコープ = test ghi ローカル変数のスコープ = test foo ローカル変数のスコープ = test ## FooMapをfor文で回してkeyとvalueを表示 キー: a 値: 111 ローカル変数のスコープ = test キー: b 値: 222 ローカル変数のスコープ = test キー: c 値: 333 ローカル変数のスコープ = test
*1: go:generateでも実行できます。参考
go-bindataをgo:generateで実行する
この手の生成ツールはgo:generateで、まとめて実行するようにすればMakefileとか書かなくていいので幸せになれそうです。
go-bindataの使い方とかは以下などを参考にしていただければと。
アセット的なアレを実行バイナリ内に入れる話。 — さにあらず
go-bindataしたファイルを参照したいmainのソースコード
ディレクトリ構造はこんな感じです。
├── data │ └── emoji.json └── main.go
//go:generate go-bindata data/
のコメントを入れる。
go-bindataをgo:generateで実行するhttp://kyokomi.hatena ...
go generateを実行する
bindata.goが生成されました。
$ go generate $ ll total 144 0 drwxr-xr-x 5 kyokomi staff 170 1 17 21:01 . 0 drwxr-xr-x 16 kyokomi staff 544 1 17 20:51 .. 136 -rw-r--r-- 1 kyokomi staff 69509 1 17 21:00 bindata.go 0 drwxr-xr-x 3 kyokomi staff 102 1 17 20:54 data 8 -rw-r--r-- 1 kyokomi staff 222 1 17 21:01 main.go
おわり
もっと色々とgo:generateで便利なやつないかな。
docomo APIのGoライブラリ(go-docomo)を作った
docomoのAPIを利用する目的で作ったGo製のライブラリです。 各API叩いてるだけなので、特別なにかやってるとかはないです。
今のところ以下のAPIに対応しています。
- 雑談対話
- 知識Q&A
- トレンド記事抽出
ライブラリの構成とかはgo-githubを参考に作りました。
docomo API
docomoAPIを利用するには、以下でDeveloper登録が必要です。 Google+とかFacebookとかのSNSアカウントでログイン対応してるので、すぐAPIを触れます。
docomo Developer support | NTTドコモ
docomoAPI
※詳しくは公式APIドキュメントを見ていただければと
利用例
大体こんな感じに使われてます。
以下の記事を見て自分もGoでやってみたいなーと思いました。
go-docomoでつくったGo製のSlackbot
いーすんさん可愛い!!!
雑なソースコードはこちら ↓
go-docomoの使い方
普通にgo get
します。
go get github.com/kyokomi/go-docomo/docomo
docomoで登録したAPIはNewClientの引数で渡すようにしているので、 環境変数なり起動引数なりで読み込んでセットしてください。
package main import ( "log" "os" "github.com/kyokomi/go-docomo/docomo" ) func main() { apiKey := os.Getenv("DOCOMO_APIKEY") c := docomo.NewClient(apiKey) message := "こんにちわ" req := docomo.DialogueRequest{ Utt: &message, } res, err := c.Dialogue.Get(req, true) if err != nil { log.Fatalln(err) } log.Printf("%+v", res) }
実行結果
2015/01/14 14:52:02 &{Context:kqRd3UD-30ov__ecH7exLA Da:0 Mode:dialog Utt:こんにちわー Yomi:こんにちわー RequestError:{PolicyException:{MessageID: Text:}}}
Memo: トレンド記事取得の関連記事取得が中々ヒットしない仕様?みたいで「ぐぬぬ」ってなりますのでご注意ください
おわり
気軽にPR等投げていただければと思います。
ただ、英語全然ダメなので、こっそりTwitterとかで日本語で話しかけていただけると助かります・・・
Go言語でのInterfaceの可視性について
ちょっとハマったのでメモがてらまとめました。
Interfaceも通常のstruct等と同じく先頭が小文字で始まる場合に別パッケージで参照できないという点についてです。
ディレクトリ構成
example ├── factory1 │ └── factory.go ├── factory2 │ └── factory.go ├── main1.go └── main2.go
外部でinterface実装可能
Factory
インターフェースのCreate()
,Register()
ともに先頭が大文字でパッケージ外から参照可能なので、別のパッケージでインターフェースを実装することが出来ます。
// example/factory1/factory.go package factory1 type Factory interface { Create() Register() }
// example/main1.go package main import "./factory1" type BarFactory struct { } func (h BarFactory) Create() { } func (h BarFactory) Register() { } var _ factory1.Factory = (*BarFactory)(nil) func main() { f1 := BarFactory{} f1.Create() f1.Register() }
外部でinterface実装不可能
Factory
インターフェースと同じパッケージ内で実装したものなら、
外部パッケージから利用可能です。
ポイント
register()
は先頭小文字で不可視になっているため、外部パッケージからはCreate()
しか呼べないregister()
は先頭小文字で不可視になっているため、外部パッケージではインターフェースの実装ができない
//example/factory2/factory.go package factory2 type Factory interface { Create() register() // 別packageから参照不可能 } type FooFactory struct { } func (h FooFactory) Create() { h.register() } func (h FooFactory) register() { } var _ Factory = (*FooFactory)(nil)
// example/main2.go package main import "./factory2" func main() { f2 := factory2.FooFactory{} f2.Create() // ERROR: 不可視なので呼び出せない // f2.register() } type BazFactory struct { } func (b BazFactory) Create() { } func (b BazFactory) register() { } // ERROR: Factory.register()が不可視なのでinterface実装できない //var _ factory2.Factory = (*BazFactory)(nil)
おわり
あまりinterfaceを使う機会がなかったので、よくわかってなくてハマりました。
(単に使い方わかってなくて使い所がわかってなかっただけかもしれませんが・・・)
触りながら自己理解したので、もし認識違い等ありましたら指摘いただけると助かります。
最近買ったもの(2014年下期編)
スワダ 爪切り クラシック L
- 出版社/メーカー: 諏訪田製作所
- メディア: ヘルスケア&ケア用品
- 購入: 2人 クリック: 9回
- この商品を含むブログを見る
確かに切れ味もよくて爪も飛び散らないいい感じ。 うまく切れた指はヤスリ掛け不要だった。
タブレットPC対応フレキシブルマウントアームスタンド
オウルテック 新しいiPad/Nexus7対応タブレットPC対応フレキシブルマウントアームスタンド シルバー OWL-MAFA03
- 出版社/メーカー: オウルテック
- 発売日: 2012/10/17
- メディア: Personal Computers
- 購入: 1人 クリック: 1回
- この商品を含むブログを見る
いい感じ!!! pic.twitter.com/vUgC8wmfdv
— きょこみ (@k_yokomi) 2014, 11月 23
と思っていたが。。。
Nexus9結構持ち歩くので、いちいちセットアップするの面倒いとかで結局ほとんど使ってない。
Qiチー対応ワイヤレス充電器(USB供給)
Qiチー対応ワイヤレス充電器(USB供給)スマホ タブレット 置くだけ充電器
- 出版社/メーカー: Remarks Japan
- メディア: エレクトロニクス
- この商品を含むブログを見る
値段的にもコスパ高くて、買って良かった。
注意点:
- ケーブル指して充電するより充電速度が遅い
- ケーブル指して充電するより端末が熱くなる
サイクロン式 2in1スティッククリーナー
ツカモトエイム ecomo サイクロン式 2in1スティッククリーナー(ショコラブラウン) AIM-SC11-BR
- 出版社/メーカー: Tsukamoto Aim
- 発売日: 2014/04/08
- メディア: ホーム&キッチン
- この商品を含むブログを見る
5年使った3980円の掃除機と別れを告げた。
吸引力が違うので時間かからないのと、コードレスなのでちょっとゴミを見かけたらサッと掃除機掛けれるのが良い。
PlayStation Vita TV (VTE-1000AB01)
PlayStation Vita TV (VTE-1000AB01)
- 出版社/メーカー: ソニー・コンピュータエンタテインメント
- 発売日: 2013/11/14
- メディア: Video Game
- この商品を含むブログ (24件) を見る
PSVitaのゲームたまに家でガッツリやるときがあるので、勢いで買ってみた。
バリューパック買わなかったの失敗した。した。。。した。。。
PS3のコントローラーあるし〜とか思ってたけど、コントローラのケーブルを刺さないと操作できないのでいちいち抜き差しするのが面倒でお蔵入りしそう。
47型テレビで使うと少し画質が悪いのが目立つけど、特別こだわりがなければ問題ない。
セーブデータに関しての注意点:
- PlayStation®Plusを登録してセーブデータを預ける(お金かかる)
- nasneにセーブデータをコピーして上書きする(めんどい)
- 1つのメモリースティックを抜き差しして使う(めっちゃめんどい)