YAPC::Asia Tokyo 2015 前夜祭に行ってきた
YAPC::Asia Tokyo 2015 の前夜祭に行ってきました。仕事終わりに埼京線からりんかい線に乗り継ぎ、国際展示場へ。ビッグサイトはちょっと時間がかかるかなと思っていましたが、空いていたので渋谷から30分ほどで着きました。
聴いたトークは3つ。メモがてらツイートしたことをはっておきます。発表者のみなさまありがとうございました。
PHP帝国の逆襲!(を願うPHPerが話す最近のPHPについてのクイックツアー PHP7対応版) - YAPC::Asia Tokyo 2015
YAPCなのに前夜祭はPHPとRubyのセッションから始まったようです。私はuzullaさんのトークを聴きにいきました。去年も聴きたかったのですが機会を逃してしまったので1年経て聴けたことになります。会場が盛り上がってて最高でした。最近HHVMをいろいろ手元で試していたのでトピック的にも面白かったです。PHP7でまたいろいろ良くなりますし、今後も楽しみです。あと「負債のない言語があるか?ないだろ。」的な流れが最高でした。
PHP最高です #yapcasia pic.twitter.com/I4AOj6UyVw
— suzuken (@suzu_v) 2015, 8月 20
この間HHVMをOSXでビルドしようとしたらこけたのでDockerでビルドしてます #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
動的片付けの言語は今後use strictを実装していくことになるのだろうか… #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
. @uzulla さんのトークを聞いていると「PHP7最高なのでは?」という気持ちになるしやっぱりPHP最高だしビールを飲みながらPHPの話を聴くのは最高なのではと思わずにいられない #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
PHP6の話はやめるんだ!!!!1 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
はてなブックマークのトピックページの裏側 - YAPC::Asia Tokyo 2015
Elasticsearchのaggregationをごりごりと活用している事例でした。はてなブックマークは日々使っているので中のお話が聴けて新鮮でした。トピックの生成、Elasticsearch 6ノードで実現されているのが最も驚いたところです。2時間ごとの生成とおっしゃっていたけれど、日によってトピックの量が変わるとジョブの時間も伸びていくのだろうか・・・など思いつつ、興味ぶかいセッションでした。
お、 #elasticsearch の話だ。Significant Terms Aggregationはたしかに便利。 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
Function Score Query
https://t.co/B5GGCDTVs7 の話。scoreでの絞り込み結果をそのまま1クエリでできるのはやっぱり便利 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
はてなブックマークの規模でaggregationとかどれくらいの負荷かかるのかな。Elasticsearchクラスタの運用面での話も気になる。あとトピック生成をどのタイミングでやってるか、とか。新しい記事が追加されたらそのタイミングでやる、とかだと結構大変そう #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
あとAnalyzerはkuromojiなのかな? #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
トピックの名前付けには Significant Terms Aggregation
https://t.co/IcIEQFi2AS を利用して重要語を抽出。その後重要文を抽出するようにしている。 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
係り受け解析にはCabochaを利用。前処理気になる。 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
トピックタイトルを短くするタスク。スマホアプリとかだと短くしたい。全角10文字以下、など。重要語の数を減らしながら短くする。基本的にはタイトル生成の流れと一緒。指定した文字数になるまで繰り返して短く、と。 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
二時間ごとにトピック作るのなかなか大変だ。ES6ノードで全トピックを生成と。 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
トピックは辞書作るより前に作られる。あー、もう新語獲得に近いタスクなんだろうなぁ。未知語でもうまくトピックになるようにする必要があるということかー #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
我々にできるOSSとそのコミュニティの育てかた - YAPC::Asia Tokyo 2015
前夜祭最終セッションはモリスさんのセッションを見に。モリスさんの経験あってこそのセッションだなあと思いました。私は利用者になってしまうことがほとんどなので、こうしてもっと自分でごりごりとOSSとして出している話を聴くと、ああもっと姿勢を変えていかないとなあと思いました。最後t-wadaさんがQ&Aで質問されていたソフトウェアがコンパクトで美しいことと、ツールの実用性との両立というのは興味深い話でありました。
あーこれはNorikraが安定しすぎていた話かなぁ。放っておいても動くから困らなかったし・・・ #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
"We can't create a super product at first" これは本当にそうだなー #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
Add new Logging driver "fluentd" by tagomoris · Pull Request #12876 · docker/docker
https://t.co/eX6LJN0JjV の話で盛り上がっている #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
ツールがコンパクトで美しいことと、何かを実現するためにソフトウェアが大きくなっていくことの話。これは、両立するのは大変だよなぁと。Goのcoreとかはこのへんうまくやってるなぁという印象がある。 #yapcasia
— suzuken (@suzu_v) 2015, 8月 20
その他
前夜祭には初めて行ったのですが、ビールが出るのですね!おいしくいただきました。ビッグサイト、広くて明日から人もたくさんくるでしょう。運営の方には頭が上がりません。明日からも楽しく、無事に3日間が終えられることを祈りつつ、楽しんでいきたいと思いました。
JAWS-UG Meguro #0 でAWS SDK for Goについて発表してきました
「カジュアルなAWSの集いをやりますよ!」というお誘いをいただいて、行ってきました。
私からは最近触り始めたAWS SDK for Goの紹介をしました。
www.slideshare.net
Gist版: https://gist.github.com/suzuken/0a7f64a6016b3edfe2c4
AWS SDK for Goはまだ開発版で、プレビューの段階です。インタフェースはわりとカジュアルに変わってしまう段階では有りますが*1、ひとまず雰囲気だけでも掴んでもらえれば、と思い紹介してみました。
発表中でも触れたように、内部ではJSONで書かれたAWSのapi仕様に則り、 go generate
をつかってコードが生成されるようになっています。また、Exampleをうまくつかうようにしていたりと、このあたりも面白いところです。
Testable Examples in Go - The Go Blog
AWSのみなさま(と、 @kani_b 氏)、会場・運営どうもありがとうございました。
*1:実際にサンプルとして書いてきたコードが、発表前日の変更で壊れたりもしました・・
Arduinoをはじめよう、をやってみた
GWだし普段やってないことをやってみよう、ということでArduinoを触ってみた。Arduinoをはじめようという本と、それに合わさったキットをつかっている。*1
- Arduinoをひとまず起動する
- LEDをつけてみる
- スイッチをon/offしてLEDをつけたり消したりしてみる
- Cdsセルをつかって、LEDをつけたり消したりする
- Cdsセルをつかって、LEDの光る強さを変えてみる
- ブログから本文読み取って、単語数をもとに3つのLEDの光る強さを変える
ということをした。所要時間5時間くらい。組み立てつつ、写経しつつ進めた。たぶんProcessingとかこういう部品組むのとか慣れてる人だったらもっと早く終わると思う。
つかったもの
環境はOSX 10.9.5のMBP。
- 出版社/メーカー: スイッチサイエンス
- メディア: エレクトロニクス
- 購入: 64人 クリック: 1,164回
- この商品を含むブログ (51件) を見る
Arduinoをはじめよう 第2版 (Make:PROJECTS)
- 作者: Massimo Banzi,船田巧
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/03/16
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 27回
- この商品を含むブログ (11件) を見る
ここからIDEを落とす。Processingで書けるらしい。Cに変換されるとのこと。
Arduino - Software http://www.arduino.cc/en/main/Software
ArduinoをはじめようキットだとArduino Unoというボードがついている。これをPCとUSBでつなぐと、Arduinoに電力が供給されて動くようになっている。ちなみに本には設定が必要だと書いてあったんだけど、USBでつないでArduinoのIDEを起動したら勝手に設定が終わっていた。簡単。接続されているデバイスの中からArduinoを勝手に認識してくれているらしい。
コード書いてチェックボタンでverify、→ボタンでコンパイルとデプロイされる。便利。
まずLEDをつけたりスイッチをつけたり
Arduino IDEで新規ファイルを作成するとSTUBの手続きが生成される。
void setup() { // put your setup code here, to run once: } void loop() { // put your main code here, to run repeatedly: }
setup()
がマイコンボードに書き込まれた際に実行される処理。 loop()
はその後繰り返し呼び出される。LEDをつけるには
void setup(){ pinMode(13, OUTPUT); // LEDのポート番号 } void loop(){ digitalWrite(13, HIGH); }
これだけでいい。ちなみに読み込みはINPUT
用のpinをつくって、digitalRead()
すればいい。するとボタンを押してLEDをつけたり消したりするのは以下のようにかける。
int val = 0; void setup(){ pinMode(13, OUTPUT); // LEDのポート番号 pinMode(7, OUTPUT); // 例えば、ボタンのポート番号 } void loop(){ val = digitalRead(7); // ボタンの値を読み込む if (val == HIGH) { digitalWrite(13, HIGH); // LED on } else { digitalWrite(13, LOW); // LED off } }
といったような感じでコードを書いていく。だいたいArduino側がapiを用意してくれているので、単純なdigitalRead()
やdigitalWrite()
だとさくさく書けるようだ。
こういった例がいくつかあって、以下の様に部品を組んで動かしていく。
微妙にはまったところ
6章にクラウドとの会話という章がある。ここで、ブログのフィードからテキストをもってきて、LEDライトのそれぞれの明るさに反映するという例になっている。
ブログのフィードを持ってきてシリアル通信でボードに送るところはProcessingで書かれている。ただこのままだと動かない。
- そもそも
http://blog.makezine.com/index.xml
が403 - Processingをインストールしてもそのままでは動かない。
processing-java
を入れる必要があり、それらのimport
宣言が抜けている。
ということでちゃちゃっと直した。https://processing.org/download/からProcessingを落としてきてインストール。Tools -> Install "processing-java" でprocessing-javaをインストール。あとは以下のimport文をスケッチに足す。
import java.net.*; import java.io.*; import java.util.*;
あとはURLを適当に変えてあげる。私は代わりに String feed = "http://blog.arduino.cc";
とした。また、ここで例にあげられているlove, peace, arduinoの単語はブログによって頻度が違うので適当に選ぶといい。私はそれぞれwindows, make, arduinoとした。
で結果として以下のようになった。
ちゃんと光った。
感想
面白かった。シリアル通信できればProcessingで処理した部分は他の言語でも書けるだろうし、もっといろいろできそう。あと色んなセンサーを集めて遊んでみたくなった。
*1:2つともwishlistからプレゼントとしてもらったもの。harukasan, amacbeeありがとう!
dummyデータをつくる
dummyデータつくるのになんかスクリプト書くかーといっていっつも使いまわしている気がしてきたのでとりあえず簡単なライブラリにしておいた。
似たようなツールはいろいろあるけど、シンプルなのが欲しかった。もうちょっとまとまったら使い方を書きたい。
みたいときに使えるようになる、予定。TODOとしては、
- 固定長以外でも出力
- JSONフォーマットで出力
- LTSVのようなフォーマットで出力
- delimiterをoptionalに
- 大きいサイズ生成する場合には並列に
あたりだろうか。DBのテストするために書いたので、CREATE TABLE
から適宜そのテーブルにいれられるダミーデータをつくれるように・・・とか一瞬思ったけど面倒そうだったのでやめた。
ローカル作業でのgitリポジトリ管理とコーディング環境の話
gitを改めてちゃんと使おうという人がまわりで増えてきたのでメモとして貼っておく。
現状の設定はこんな感じ。1年くらい変わってなかった。
https://github.com/suzuken/dotfiles/blob/cbf8e7168c96029d535d69f981337d23aacfa51c/gitconfig
特にaliasまわりは普段つかっているのであげておく。
[alias] # http://oli.jp/2012/git-powerup/ # http://blog.blindgaenger.net/advanced_git_aliases.html alias = !git config --list | grep 'alias\\.' | sed 's/alias\\.\\([^=]*\\)=\\(.*\\)/\\1\\\t => \\2/' | sort b = branch -a br = browse-remote ci = commit co = checkout current-branch = rev-parse --abbrev-ref HEAD d = diff dc = diff --cached di = diff dic = diff --cached f = fetch --prune fs = !git f && git su ignore = !([ ! -e .gitignore ] && touch .gitignore) | echo $1 >> .gitignore info = remote show origin l = log --graph -n 20 --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(green)- %an, %cr%Creset' ll = log --stat --abbrev-commit ln = log --graph -n 20 --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(green)- %an, %cr%Creset' --name-status lp = log --oneline -n 20 -p ls = log --stat --abbrev-commit -n 1 # display previous log s = status --short --branch st = status su = submodule update delete-merged-branches = !git branch --merged | grep -v \\* | xargs -I % git branch -d % fetch-pulls = fetch origin +refs/pull/*:refs/remotes/pull/*
特によく使うのは delete-merged-branches
と fetch-pulls
。remoteでbranchがマージされてfetchしてきたときに既にmergeしてるものだけどlocalブランチから消す。これをやると現在mergeされていないブランチのみが残るので便利。 fetch-pulls
はcodeをレビューするときとかにつかっていて、これをつかうと対象プロジェクトのPull Requestをまとめてfetchできる。するとローカルでdiffもとりやすいし便利。
あとはマージにはvimdiffを使ってる。それと git clone
は ghq clone
motemen/ghq でつかっていて、全部GOPATHっぽく入るようになってる。これを peco
peco/peco で探すようにしているので、大分ローカルでのリポジトリの移動が楽になった。普段はvimでコーディングしているので mattn/ctrlp-ghq でプロジェクトを行ったり来たりしている。だいたい新しいtab開いて ctrlp-ghq
でcurrent directoryを移動して Dirvish
justinmk/vim-dirvish でそこのrootを開く、ということをしてることが多い。基本的に全部動作が軽いのを選ぶようにしてる。
気が付くとvimの話になってしまったので反省している。
参考
React.jsをもくもくと触り始めた
とりあえず触ってみないとわからないのでもくもくとチュートリアルをなぞっていく。
A JavaScript library for building user interfaces | React https://facebook.github.io/react/
Starter Kit 0.13.1でさわる
wget https://facebook.github.io/react/downloads/react-0.13.1.zip
unzip react-0.13.1.zip
Getting Started | React をひたすらなぞる
https://facebook.github.io/react/docs/getting-started.html
これをなぞっていく サンプルが下のとおり
<!DOCTYPE html> <html> <head> <script src="build/react.js"></script> <script src="build/JSXTransformer.js"></script> </head> <body> <div id="example"></div> <script type="text/jsx"> React.render( <h1>Hello, world!</h1>, document.getElementById('example') ); </script> </body> </html>
text/jsxとなっているのがJSXと呼ばれているXML
JSX in Depth | React https://facebook.github.io/react/docs/jsx-in-depth.html
Reactを使う場合に普通のplainなJSをつかってもいいらしい
var myDivElement = <div className="foo" />;
React.render(myDivElement, document.body);
このようにJSの構文の中にXMLでの記述ができる
これをそのまま React.render
でオブジェクトをつくり、レンダリングできる。
ひとまず簡単にReactを利用したコードを書いて最初のhelloworld.htmlに食わせる。 src/helloworld.js
として保存する。
React.render( <h1>Hello, world!</h1>, document.getElementById('example') );
buildのためにツールを入れる
-> % npm install -g react-tools
/usr/local/bin/jsx -> /usr/local/lib/node_modules/react-tools/bin/jsx
react-tools@0.13.1 /usr/local/lib/node_modules/react-tools
├── jstransform@10.1.0 (base62@0.1.1, source-map@0.1.31, esprima-fb@13001.1001.0-dev-harmony-fb)
└── commoner@0.10.1 (private@0.1.6, commander@2.5.1, graceful-fs@3.0.6, install@0.1.8, q@1.1.2, mkdirp@0.5.0, iconv-lite@0.4.7, recast@0.9.18, glob@4.2.2)
これで jsx
コマンドがつかえるようになる。buildをしてみる。
jsx --watch src/ build/
すると src/
にさっき配置した helloworld.js
がビルドされる。同名のファイルが build/
に配置される。
-> % cat build/helloworld.js
React.render(
React.createElement("h1", null, "Hello, world!"),
document.getElementById('example')
);
また、これに応じてhtmlを書き換える。
<!DOCTYPE html> <html> <head> <script src="build/react.js"></script> </head> <body> <div id="example"></div> <script src="build/helloworld.js"></script> </body> </html>
これでHelloWorldが無事表示される。さきほどHelloWorldのDOMを貼り付けていたところに、scriptを貼り付けていることがわかる。ちなみに、下のようにheadに貼っても表示されない。
<!DOCTYPE html> <html> <head> <script src="build/react.js"></script> <script src="build/helloworld.js"></script> </head> <body> <div id="example"></div> </body> </html>
Tutorial | React をなぞる
次はtutorialを読めと書いてあったのでなぞる https://facebook.github.io/react/docs/tutorial.html
まずこれを型として、text/jsxのところに演習内容をいれていく
<!-- index.html --> <html> <head> <title>Hello React</title> <script src="https://fb.me/react-0.13.1.js"></script> <script src="https://fb.me/JSXTransformer-0.13.1.js"></script> <script src="https://code.jquery.com/jquery-1.10.0.min.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx"> // Your code here </script> </body> </html>
まずコンポーネントをつくってみる
var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> Hello, world! I am a CommentBox. </div> ); } }); React.render( <CommentBox />, document.getElementById('content') );
レンダリングされ、divができている。ちなみにレンダリングされているDOMをみてみると以下のようになっている。 data-reactid
というプロパティがある。これでreactが生成したDOMを管理しているのだろうなと想像。なんで0
じゃなくて.0
なのかはしらない。
<div id="content"> <div class="commentBox" data-reactid=".0"> Hello, world! I am a CommentBox. </div> </div>
次にこれをplainなJavaScriptでやる方法も書いてる、が面倒なので飛ばす。JSXで書いたほうがDOMつくるのはシンプルに書けるっぽさ。ああでもコメントに書いてあるけど、Reactでの div
は実際のDOMのノードとは違うらしい。なんのことだろ。
次にcomponentをつくることを学んでいく。ちなみに下のコードのままでは書きかけなので動作しない。
var CommentList = React.createClass({ render: function(){ return ( <div className="commentList"> Hello, world! I am a CommentList. </div> ); } }); var CommentForm = React.createClass({ render: function(){ return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); // CommentListとCommentFormを含んでいる var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } }); // propsでpropertyを取得できるらしい // props = properties だと思われる // こうすることで、`Comment`で`CommentList`からのデータを読むことができる // this.props.childrenでnestした要素をとれるらしい var Comment = React.createClass({ render: function() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> {this.props.children} </div> ); } });
次にpropsを利用していく。
// CommentListのなかでCommentを利用している。かつ、propとしてauthorを設定している。 var CommentList = React.createClass({ render: function(){ return ( <div className="commentList"> <Comment author="Pepe Hunt">This is one comment</Comment> <Comment author="Jordan Walke">This is *another* comment</Comment> </div> ); } }); var CommentForm = React.createClass({ render: function(){ return ( <div className="commentForm"> Hello, world! I am a CommentForm. </div> ); } }); var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> <CommentForm /> </div> ); } }); // これはmarkdownへの変換器 var converter = new Showdown.converter(); // `{}` のなかでは普通にJavaScriptのmethodが使えている // 普通にconvertしたHTMLを表示しようとしても<em>が文字列として出力されてしまう // なので、ReactによるXSS対策を無効にするために、innerHTMLをつかうようにしている var Comment = React.createClass({ render: function() { var rawMarkup = converter.makeHtml(this.props.children.toString()); return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={{__html: rawMarkup}} /> </div> ); } });
markdownの表示のところはイレギュラーかも知れないが、Reactのレンダリング方針がかいま見える。
次に外部からデータを当て込んでいく。
var data = [ {author: "Pepe Hunt", text: "This is one comment"}, {author: "Jordan Walke", text: "This is *another* comment"} ]; var CommentList = React.createClass({ render: function(){ var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ) } }); // CommentListに対してdataのプロパティを渡すことができるのか var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.props.data} /> <CommentForm /> </div> ); } }); React.render( <Commentbox data={data} />, document.getElementById('content') );
こうすると data
をrender時にCommentBoxに渡すことができる。data
をオブジェクトとして渡していたのを外部から渡すには以下のようにする。
React.render( <Commentbox url="comments.json" />, document.getElementById('content') );
comments.jsonは以下のとおり。
[ {"author": "Pepe Hunt", "text": "This is one comment"}, {"author": "Jordan Walke", "text": "This is *another* comment"} ]
で、apiとして返せば連携できるようになるはず。
// getInitialStateでprops.dataを初期化している var CommentBox = React.createClass({ getInitialState: function() { return {data: []}; }, // ここは単純にserver sideリクエスト // ひさびさにjQueryみた 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) }); }, // componentがレンダリングされると呼ばれる componentDitMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, // this.state.dataで参照できる render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } }); // sleepのためのintervalもわたしてる。 // 2000をintでわたしたいから{}にしてるのか React.render( <Commentbox url="comments.json" pollInterval={2000} />, document.getElementById('content') );
これでサーバサイドに問い合わせて、componentにデータを引き渡しレンダリングするところまでできたことになる。
次にコメントを投稿できるようにする。
var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = React.findDOMNode(this.refs.author).value.trim(); var author = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } React.findDOMNode(this.refs.author).value = ''; React.findDOMNode(this.refs.text).value = ''; return; }, render: function(){ // refのプロパティをつけておくと、上でReact.findDOMNodeでDOMを参照できる return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text"/> <input type="submit" value="Post" /> </form> ); } });
onSubmitのイベントをhandleSubmit
で受け取っている。実際の送信処理を下のように書く。
var CommentForm = React.createClass({ handleSubmit: function(e) { e.preventDefault(); var author = React.findDOMNode(this.refs.author).value.trim(); var author = React.findDOMNode(this.refs.text).value.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({author: author, text: text}); React.findDOMNode(this.refs.author).value = ''; React.findDOMNode(this.refs.text).value = ''; return; }, render: function(){ // refのプロパティをつけておくと、上でReact.findDOMNodeでDOMを参照できる return ( <form className="commentForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" ref="author" /> <input type="text" placeholder="Say something..." ref="text"/> <input type="submit" value="Post" /> </form> ); } }); var CommentBox = React.createClass({ getInitialState: function() { return {data: []}; }, 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) }); }, // コメントをしたらここでコメントをサーバにおくる handleCommentSubmit: function(comment) { // コメントが返ってくるに空でも表示しておく var comments = this.state.data; var newComments = comments.concat([comment]); this.setState({data: newComments}); $.ajax({ url: this.props.url, dataType: 'json', type: 'POST', data: comment, success: function(data) { this.setState({data: data}) }, error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, componentDitMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm onCommentSubmit={this.handleCommentSubmit}/> </div> ); } });
これでひと通りコメントの追加、表示などができるようになったことになる。
新社会人エンジニアに向けて
新卒一年目の時にやっておけばよかったこと、というネタ振りで社内日報に書いた。こっちにも貼っておく。
- 毎日コードを書こう。業務では様々な事情で打合せが増えたりして悶々とすることもある。良いコードを書けない人はコードを書いてる絶対量が少ない。コードを書こう。
- 全部やろうとしなくていい。自分の関わっているシステムについて全部やらなくていい。でも、どれくらいの広さがあるのかを知ることはやったほうがいい。それで、自分がどこの領域で価値を出せるかを見定めて、相談して、コードを書こう。
- 幸いなことに、続けていると仕事は面白くなる。長く取り組める環境をみつけて、じっくり問題に取り組もう。研究と似て非なる部分は、これは仕事のコードで、様々な人達が関わっているということだ。チームで仕事をするのは楽しい。また、大勢でいろんな思惑をもって動いているというシステムに携わるというのは、なかなか得がたい経験である。この環境を楽しもう。
新卒一年目のときから変わった習慣もあるけど、そんなに入社当時から変わっていないなと思った。新社会人のみなさん、おめでとうございます。