2017年を振り返る
2018年になって早くも三が日が終わりそうですがいまさら2017年を振り返ります。 なお去年の振り返りはこちらです。
Kawasaki.rbの公式ブログを書き続けて2年と9ヶ月
Kawasaki.rbの公式ブログを一昨年の4月から毎月休まず寄稿しつづけて2年と9ヶ月が経過しました。
パーフェクトRuby読書会は相変わらず参加者達の楽しい脱線解説*1により遅々として進まず2017年5月にはとうとう第二版が出てしまいましたが、Rubyの話を中心にさまざまな技術が聞けるのがKawasaki.rbのとても素晴らしいところです。
参加者達もそのことは充分理解しており、読書会後のセッションでも「今日はGoの話をします」「Pythonで野球分析する話もってきました」「今日は珍しくRailsの話がありましたね」という言葉が飛び交っています。
社内の非エンジニアに向けて自社サービスにまつわる技術講習を行った
弊社の非エンジニアは、エンジニアではなくても仕事柄HTML/JS/CSSを触る機会も多く、提供しているサービスの機能によりCookieやリファラなどのWeb上の技術を知っていなければならないという割と高度な仕事を要求されているため、お客様からの問い合わせや開発者チームとの会話がよりスムーズになれば良いと思い技術講習を行いました。
内容は全3回に分けて行い、
- 自社サービスが動作している仕組み(GoogleDevToolを使ったHTTPリクエスト/レスポンスの眺め方)
- 提供している機能にまつわるWeb技術の解説(Cookie,リファラ,DOM,URLの構造)
- CSS演習(別のデザイナにお願いした)
という内容で実施しました。得られた効果としては、実施後のサーベイから「深い理解からお客様により詳しく機能を案内することができた」「GoogleDevToolを使い機能が動かない原因特定の助けになった」というものがありました。
サービスに関係ない知識を教えたり、座学だけでは実務に活かすことは難しいと思い、講習では「何を教え、何を教えないか」に充分注意しつつ、GoogleDevToolを通したハンズオンで実際に体験してもらうことに重きを置きました。
この話はきちんとまとめて、別途ちゃんと発表したいと思います。
さいごに
今年はいよいよ20代最後の年になってしまうので、良き30歳を迎えられるよう悔いの残らないように精進したいと思います。
react-reduxのconnectとは何なのか
だいぶ端折っているので本家を読んだほうがいいです。
何なのか
簡単に言えばReactComponentをReduxのStoreに繋ぐもの。ReactComponent自体には手を加えず、Reduxに接続された新しいComponentを返す。ReduxではContainerと呼ばれる。
できること
引数として以下を渡すことができる。
- mapStateToProps
- mapDispatchToProps
- mergeProps
- options
特に重要なのはmapStateToPropsとmapDispatchToPropsである。
mapStateToProps
Storeが更新される度に呼ばれる。つまり、アプリの状態が変化したときのコールバック。Reactを単体で使用した場合、イベントが発生したらルートのComponentから末端のComponentまでバケツリレーしながら状態を変化させなければならないが、それをしないですむようになる。 mapStateToPropsが返す値はプレーンなObjectでなければならない。Storeを監視したくなければnull/undefinedを返せば良い。
mapDispatchToProps
ReduxComponentのイベントとReduxのActionを結びつける。
mergeProps
mapStateToProps()、mapDispatchToProps()、親コンポーネントのpropsの結果が渡される。つまり決定したpropsをここで改変することができる。省略すると Object.assign({}、ownProps、stateProps、dispatchProps)
が呼ばれる。
options
connectorの振る舞いを変えることができる。
- pure(Boolean) … propsが変更されていない場合、再レンダリングを行わない。デフォルトは
true
。 - areStatesEqual(Function) … pureのstateが等しいか判定基準となる関数。デフォルトは
===
- areStatePropsEqual(Function) … pureのpropsが等しいか判定基準となる関数。デフォルトは
shallowEqual
- areStatePropsEqual(Function) … pureのmapStateToPropsが等しいか判定基準となる関数。デフォルトは
shallowEqual
- areMergedPropsEqual(Function) … pureのmergedPropsが等しいか判定基準となる関数。デフォルトは
shallowEqual
街コロの期待値を出す
街コロとは
これ
- 出版社/メーカー: グランディング
- 発売日: 2012/05/13
- メディア: おもちゃ&ホビー
- この商品を含むブログを見る
ルールなどはここ などを参照して欲しい。
モチベーション
どうやっても序盤は森林を買い、周りが駅を建てるに連れて鉱山/家具工場への流れが最強な気がしているんだが、ここまで売れているゲームなのだから他の戦略もあるのだろう、と思い各カードの期待値を出してみた。
コード
建物の数やプレイヤー数で収入が変動するものは除外
期待値はプレイヤー1週で得られる収入
サイコロの数は全員同じとする
結果
プレイヤー数(試行回数): 4 麦畑(blue) 目:[1] コスト:1 収入:1 サイコロが1つ 期待値:2/3 元が取れるターン数:2 サイコロが2つ 期待値:0 元が取れるターン数:Infinity 牧場(blue) 目:[2] コスト:1 収入:1 サイコロが1つ 期待値:2/3 元が取れるターン数:2 サイコロが2つ 期待値:1/9 元が取れるターン数:9 パン屋(green) 目:[2, 3] コスト:1 収入:1 サイコロが1つ 期待値:1/3 元が取れるターン数:3 サイコロが2つ 期待値:1/12 元が取れるターン数:12 コンビニ(green) 目:[4] コスト:2 収入:4 サイコロが1つ 期待値:2/3 元が取れるターン数:3 サイコロが2つ 期待値:1/3 元が取れるターン数:6 カフェ(red) 目:[3] コスト:2 収入:3 サイコロが1つ 期待値:3/2 元が取れるターン数:1 サイコロが2つ 期待値:1/2 元が取れるターン数:4 森林(blue) 目:[5] コスト:3 収入:1 サイコロが1つ 期待値:2/3 元が取れるターン数:5 サイコロが2つ 期待値:4/9 元が取れるターン数:7 鉱山(blue) 目:[9] コスト:6 収入:5 サイコロが1つ 期待値:0 元が取れるターン数:Infinity サイコロが2つ 期待値:20/9 元が取れるターン数:3 ファミレス(red) 目:[9, 10] コスト:3 収入:2 サイコロが1つ 期待値:0 元が取れるターン数:Infinity サイコロが2つ 期待値:7/6 元が取れるターン数:3 リンゴ園(blue) 目:[10] コスト:3 収入:2 サイコロが1つ 期待値:0 元が取れるターン数:Infinity サイコロが2つ 期待値:2/3 元が取れるターン数:5
感想
鉱山の期待値が20/9というのはぶっ壊れ性能では…
序盤はカフェが強い。駅が揃い始めたら建てる必要はないだろう。
プレイヤー人数が増えるほど緑(自分のターンでのみ収入が得られる)カードの効果は薄まる。緑の収入全体的に増やした方が良かったのでは…?と思うくらい。
標準ルールでは全ての建物を自由に選択できるので戦略が固定化されがちだが、拡張ルールでは序盤に建てられる建造物が限定化されておりランダム性が増すので、こちらで遊んだ方が楽しそう。
ゼロからReduxを学びボドゲのシミュレーターを作った
モダンなJSの開発環境とReact/Reduxを習得したくて、課題としてちょうどハマってたボドゲのシミュレーターを作った。
デモ
ソース
ReactとFluxは一時期趣味で触ったことがあるくらいで、記事を遡ったら既に2年前の話だった。
技術選定
ビルドツール
babel/Webpackを使用。小規模なJSにbabelを使いたいだけであればbabelifyを通すだけで良さそうだが、今回はきちんと学ぶという名目なのでWebpackをちゃんと整備することにした。後々css-loaderを使ってCSS Modulesを試すこともできたのでこの選択は良かった。
AltJS
型が欲しいと思いTypeScriptかFlowで迷った。TypeScriptは現在ReactやAngularでもサポートされており、息が長そうで学ぶ価値は高そうという印象だが、既にbabel/Webpackでビルド環境を構築しており、ここからts-loaderを導入してTS用の環境を作るのが面倒だった(この時点で既にビルド環境構築に1週間ほど費やしている)ので、今回はbabel/Webpackに比較的乗せやすいFlowを選択した。
テスティングフレームワーク
node.jsでサーバーを立てた時にmochaでテストしていた経験はあったが、今回はReduxも推しているJestにし、assertはpower-assertを使ってみた。Jestはmochaと比較しても記法は対して変わらないので学習コストとしては大したことはなかった。デフォルトでMockになるので単体テストが容易という特徴があるらしいが、依存しているモジュールが少ないせいか今回はあまり恩恵を受けられなかった。
デザイン
同僚からantが綺麗で良いというオススメをもらったがmaterial-uiが使いたかった。使ってから気づいたがmaterial-uiにはBootstrapのGrid Systemは標準では存在してなさそうで、導入したければ恐らくサードパーティのものを使う必要がありそうだった。
エディタ
最近AtomからVS Codeに乗り換えたのでこれで書いている。Flowを入れてから気づいたが、VS Codeで型を定義すると.tsでないと使えないぞと怒られる。*1
これを回避するにはVS Codeの設定で "javascript.validate.enable": false
とすれば良いのだがあまりに場当たりっぽい。
下記設定を試したところjsのコードハイライトが消えてしまったのですぐ戻した。
"files.associations": { "*.js": "flow" }
Issueの方でも正式な解決策は無さそうで今のところは警告を無視するしかなさそうな気がしている。つらい。
デプロイ
静的サイトなのでgh-pagesを使いGithub pagesにデプロイした。1コマンドでデプロイできめっちゃ便利である。
npm gh-pages めっちゃ便利やん
— ぺら (@Peranikov) 2017年3月13日
Redux所感
このくらいの規模のアプリケーションであれば正直Vue.jsを使ったほうが速く書けるし設計もさして重要ではなさそうである。各レイヤーの役割を覚えるまではコードが分散するので追っていくのが大変だが、慣れてくればどこを修正すれば良いのかがすぐわかるので後のメンテナビリティは上がりそうな気はした。
Modelレイヤー
Reduxを書き始めてすぐに気になった所は、どうやらロジックがreducerに集中してどんどんFatになっていく気がした。なので、下記記事を参考にimmutable.jsとModelレイヤーを導入した。*2
モデルにロジックが集約していくのでテスタビリティも向上し、ロジックの見通しも良くなったと思われる。
Redux、初期からModel層意識してかないとすぐにカオスになるのでは
— ぺら (@Peranikov) 2017年3月6日
それとは別に、Containerなどでコレクションのフィルタリングをしているのだが、モデルの構造を意識してフィルタリングしたくなく、もっと抽象的に扱うためにファーストクラスコレクションを導入したくなった。が、immutable.jsのコレクションは直接拡張することはどうやら難しそうで、公式でないextendable-immutableを用いれば実現できそうな気がしたが、なんとなく依存を増やしたくなく、PureなJSで色々試していたがあまりうまくいかなかった。良い例があったら知りたい。
Constantsの意味
ReduxではActionとReducerはActionTypeという文字列のキーを使ってロジックを紐付けるのだが、わざわざ定数を介する意味が見えず最初は直接文字列で書いていた。途中で気になって調べたところ、下記記事からメリットが複数あることがわかった。
要約すると、
- ActionTypeの一覧性が1つのファイルに集約するので、既存のアクションが把握しやすく名前の一貫性を保ちやすくなる
- IDEを使っていれば補完が効くのでタイプミスを誘発しにくくなる
- 変数名を介してアクセスするので、minifyの効果が向上する
ということで、ActionTypeのファイルを設けることにした。
デバッグ
イベントが発生後にStoreがどのように変化したかデバッグするために方法を探ったところ、redux-devtoolを見つけた。redux-devtoolはとても高機能で、Storeの状態を確認する以外にもActionのUndoやResetが可能らしいのだが、専用のComponentを導入する必要があったり、コードを多く変更する必要がある印象を受け、敷居の高さを感じ今回は見送った。それとは別にredux-loggerというものを見つけた。こちらはイベントの度にStoreの変更前と変更後をロギングしてくれ、比較的導入も楽で必要十分と感じたのでこちらを使用した。
テスト
公式を参考にaction/component/reducerのテストを書いてみたが、ロジックが大したことないのもあって、あまり必要性を感じなかった。Actionは外部APIを叩いたり非同期な処理が増えてくると有用性も高まるかもしれない。Componentsのテストも試しに書いてみたが、デザイン性に大きく関わる部分なのでどういう観点でテストを書けば良いのかがまだあまり掴めていない。Componentsにロジックが寄るのは恐らく設計としてあまりよろしくなさそうだし、UIについてはE2Eテストを別途設けたほうがむしろ有用ではないかという疑念が残っている。
さいごに
ダンジョンオブマンダムは良ゲーだったので買って遊ぶと良い。
- 出版社/メーカー: オインクゲームズ
- 発売日: 2013/11/26
- メディア: おもちゃ&ホビー
- この商品を含むブログを見る
2016年を振り返る
今年も今日を含めてあと2日で終了するので振り返っておく。
なお去年の振り返り。
川崎Ruby会議やった
スタッフとスピーカーという立場で参加した。自分の中では今年一番大きなイベントだったと思われる。気になるのは来年もやるのかというところだがまだ何も決まってはいない。Kawasaki.rbは土地柄かWeb屋が少なくRuby以外で仕事してる人のほうが割合として多い*1ので、今年の川崎Ruby会議もそのカラーを前面に出し、コンテンツも特にRubyにこだわらずに実施した。もし次回があるのであれば、このカラーは続けていって欲しいと思うし、そんな内容でも聞いてみたいと思う人は是非参加して欲しい。
なおkawasaki.rb公式ブログは今年からMediumに移行して絶賛継続中である。去年の4月から毎月休まず寄稿しているぞ。
データの民主化とSQLハンズオン
今年はやたら「データの民主化」という言葉が耳に入った年だと思う。弊社でもRe:dashが整備され、非エンジニアがデータベースにSQLを投げられる環境は整われた。
ただ、環境は整備されても初めてSQLを投げるのはハードルが高く、当初はその人の席で直接SQLを教えながら手伝っていたのだが、手も回らないし全体的に基礎的な事を先に教えた方が良かろうと思いハンズオンという形式で実施した。
なおこの記事の2週間後に第2回を実施している。内容は1回目で苦戦したJOINとGROUP BYを図解込みで解説し、残りの時間で難題かと思われたサブクエリの演習をした。講習でなくハンズオンという形にしたことで、課題を解けたという達成感と実際のデータ取得に応用してみようというモチベーションに繋がったと思う。現に、弊社SlackのSQL質問チャンネルでは既にエンジニアを介さずに質問と解答が繰り広げられていた*2。
技術スタック
川崎Ruby会議ではScalaについて話してみたものの、結局あまりScalaには触らず、仕事ではRubyを使うことのほうが断然多かった。今年はモニタリングとパフォーマンスチューニングをすることが多かったからか半インフラ業のような仕事が多く、DockerとGatringで負荷テスト、Passengerのチューニング、AWSのサービス(Lambda, CloudWatch, ElasticBeanstalk...)と仲良くなった。特にLambdaとSlackは監視に使うには本当に便利で、最近ServerlessFrameworkも覚えたしどんどん活用していきたい。
あとCUIツールとか今はRubyで書いちゃうんだけど、配布とか考えるとGo覚えてさくっと書けるようになりたい。
まとめ
気の利いたまとめを書こうと思ったが特に何も思い浮かばなかったのであえて書かない。
皆様良いお年を。
社内向けにSQLハンズオンやった
弊社内でRe:dashが整備され、エンジニア以外でもブラウザから気軽にSQLが叩ける用になった。 ただ気軽になったと言ってもいきなりSQLを使いこなせるわけはないので、社内向けに1時間程度のハンズオンを実施したのでここにまとめておく。
目的とゴール
目的はとりあえずSQL(主にSELECT文)の勘所を掴んでもらい、基本的な質問などは非エンジニア部署のメンバー間で解決できるようにしたかった。
なので今回のハンズオンのゴールは
- 基本的なSELECT文が叩ける
- Re:dashの基本的な操作ができる
という点に設定した。SELECTで使用する句の範囲は
- WHERE
- ORDER BY
- LIMIT
- GROUP BY
- HAVING
- サブクエリ
とre:dashの簡単な解説とした。
進行方法
自分が前に登壇してセミナー形式にしても良かったのだが、なんとなく退屈になりそうという点と、自分たちで調べて解決したという達成感があった方が身につきやすいのではという実験的な試みから以下のようにした。
- いきなり制限時間5分の課題を解いてもらう(ex. あるテーブルの◯◯ごとの件数上位n件を表示せよ)
- 課題には関連するテーブル名やカラム名、使用するSQLの句をヒントとして付随させる
- SQLの句の使い方はぐぐって調べてもらう
- 解けたものは解けてない者の手助けをしてよい
- 5分経ったら解答例提示、解答の解説、質疑応答
- これらの繰り返し
互いに教え合うという点は、幸いメンバーの技量が
とバランスが良かったのでうまくまわった。
得られた効果
セミナー形式と違って自分たちで問題を解くので、実際にSQLを叩く中でハマりやすいポイントと、細かい疑問(各句は大文字小文字どちらが良いのか、改行する意味はなんなのか、COUNT(*)に指定するカラム名はなんでも良いのかなど)も浮き彫りになり、それらを解消することができた。
また、教え合うことで主催者の手が回らず質問できないという事象を避けることができ、無事にほぼ全員が解答まで導けることができた。なにより楽しかった、またやって欲しいという声もいただけた。
反省点
INNER JOINやGROUP BYなど、少し複雑になるケースの解説はもう少し厚くした方が良かった。テーブルのイメージを把握してもらうために多くの図解を加えるべき。(INNER JOINで結合するカラムはRailsの規則によるところがあるので、さらに多くの解説を要した)
1時間でやってみたところ途中までしか終えられず、さらに解説を多く含めるのであれば何回かにパート分けした方が良さそうである。
川崎Ruby会議 01の実行委員 & 発表しました #kwsk01
2016/8/20に開催された、川崎Ruby会議 #01 の実行委員と発表をやらせていただきました。
事の発端
会の内容はるびまに、開催に至った経緯などは実行委員長のブログに任せるとして、個人的に実行委員になった背景を書きます。
僕は2015年1月からKawasaki.rbに通い続け、その後2015年4月からKawasaki.rb公式ブログの中の人を務めるようになり、その甲斐もあってか本家Ruby会議の帰りにchezouさんに川崎Ruby会議を企画しているので手伝ってもらえないかと声を掛けられ、その後正式に依頼されたので引き受けることにしました。
実行委員としてやったこと
こういった実行委員は初めての体験だったので、気づいたことと落ちているタスクは積極的に拾っていこうと思いながら手伝っていました。大きなものではWebページのロゴとスタッフTシャツ作成と当日のるびま用撮影担当、細かいことではミーティングのスケジュール調整やWikiのメンテ、懇親会会場の確保などをしていました。
発表したこと
実行委員でありながら「Rubyistを誘うScalaの世界 2.0」というタイトルで発表させていただきました。
Ver 1.0は一度Kawasaki.rbで発表したのですが、今度は20分枠ということで、未経験者にもより丁寧にScalaの説明と魅力を伝えられるよう心がけました。
参加者でScalaを触ったことあるか質問してみたところ、半数以上が手を上げた気がしたのでもう少し内容を厚くしても良かったのかもしれませんが、発表後に面白いと言ってくださった方もいたので良かったです。
妻は偉大
当初、Webサイトのロゴは用意しない流れだったのですが、折角なので妻に「kwskバザーで連想できるロゴ描いてみてくれない?」と聞いてみたら何パターンか描いてくれて、メンバーに見せたところ思いのほか好評だったので採用に至りました。その後TMIXさまからTシャツスポンサーの申し出があり、ロゴをそのままTシャツのデザインに使いまわそうとしたところ、妻に「そのまま使えるわけないだろ」とありがたいお言葉をいただき、Tシャツのデザインも新たに描き下ろしてもらいました。本当に頭が上がりません。前回の神奈川Ruby会議や東京Ruby会議11のロゴも実行委員長の妻によって描かれたものらしいので、Regional RubyKaigiは妻によって支えられていると言っても過言ではないでしょう*1。
なお発表のスライドの4ページ目の通りなのでこんなものをしれっと用意してあります。何卒...!何卒...!
さいごに
発表・参加いただいた皆様、どうもありがとうございました!また機会がありましたら参加いただけると嬉しいです!
写真はスタッフTシャツのままカレーを食べに行くスタッフ達
*1:多分