読者です 読者をやめる 読者になる 読者になる

RuboCop とつきあう方法

こんにちは、元主夫の id:eitoball です。約5年ほどの試用期間*1を経て、今年4月から、Misocaにてフルタイムで開発しています。時事ネタは特にないですが、この夏に発売予定の Starcraft: Remastered を楽しみにしている今日この頃です。

今回は、本格導入してから、2年半になる RuboCop というツールについての話をしたいと思います。

RuboCop とは?

f:id:eitoball:20170526093756p:plain

RuboCop は、Rubyのコードが、コーディング規約に沿って書かれているかを静的にチェックしてくれるツールです。コーディング規約は、 Ruby Style Guide が、ベースとなっています。

RuboCop の導入

Gemfilerubocop gem を追加して、bundle install しました。rubocop と実行すると最初は、多くの警告が出てしまうので、rubocop --auto-gen-config で、.rubocop.ymlrubocop_todo.yml という設定ファイルが作成されました。.rubocop_todo.yml 内では、一旦、全ての検知項目が、無効にされていました。

Jenkins で、CIをしているので、rubocop を実行して、警告がある場合は、ビルドを失敗とするようにしました。 rubocop-checkstyle-formatter を開発して、Checkstyle 形式で警告を出力して、Jenkins の Checkstyle プラグインで、違反箇所が、Jenkins の UI から、分かるようにしました。

f:id:eitoball:20170526094327p:plain

無効にした警告の有効化

一旦、無効にした検知項目は、少しずつ有効にしていきました。できるだけ早く全ての検知項目を有効にして、違反するコードを増やさないようにしたかったので、次の方針で有効にしていきました。

  1. 可能な限り、RuboCop がデフォルトで有効にする。
  2. 1行の文字数などの検知項目は、とりあえず、その時点での最大値を使って有効にする。最大値が、他と比べて、極端に大きい場合は、マジックコメント(# rubocop:disable ...)で、その箇所のみを無効にする。
  3. 警告を修正する場合は、 rubocop -a で自動修正して、手動で修正する必要な箇所は、マジックコメントで、特定の箇所のみ無効にする。

検知項目を有効にする場合は、有効にするプルリクエストを作成して、チームによるレビューを経て、マスターブランチにマージしていきました。わかりやすくて、チームの合意が簡単に得られそうなインデントや行末の不要な空白などのレイアウト関連の警告は、5つ程度まとめて有効にしていきました。ハッシュの記法など議論が起こりそうな警告や変更が多い警告の場合は、1つずつ有効にしました。

f:id:eitoball:20170526102409p:plain

RuboCop の更新

RuboCop の更新に伴い、新しい検知項目が増えていきます。Misoca では、bundle update して、使用している gem を週に1回更新するようにしていて、RuboCop の更新は、大体月に1回程度です。新しい指摘項目が増える場合は、一旦、それらを無効します。それから、前述の方針で、できるだけ早く全ての指摘項目を有効にしていきます。

最新のバージョンを使う上で、注意したいのは、RuboCop の不具合や誤検知です。その場合は、問題のありそうな警告を無効にして、次のバージョンまで様子を見るのも良いと思います。もしくは、修正して、プルリクエストを出すのも良いと思います。同僚の id:mzp や僕は、プルリクエストを出して、貢献しました。

github.com

github.com

github.com

RuboCop を導入したメリット

RuboCopを導入してからは、プルリクエストでのレビューコメントで、記法についての指摘をすることが、無くなり、変数やクラス名についてを考えるとか他の重要なことについての時間を使うことができるようになりました。また、規約に関する指摘は、人からより、機械からの方が、角が立たなくて、心理的な負担がなくなりました。

さいごに

Misoca では、コーディング規約を守ってコードを書きたい几帳面な開発メンバーも募集しています。ご興味ある方は、是非、応募して下さい。

*1:事実は、家庭の都合で、パートタイムで開発していました

React・Reduxはじめました

こんにちは!
Misoca開発チームのめろたん(@renyamizuno_)です!

暖かくなってきて眠いですね。

最近は、「0.8秒と衝撃。」というバンドが活動を終了するってことを聞いて、まじかーとなってます。

はい。

今回はMisocaでReactを使い始めたことについて書きたいと思います。

React

詳しく書かないですが、ReactはFacebookで作られたユーザインタフェースを構築するためのライブラリです。

github.com

仮想DOMでJS界隈を賑わせていましたね。

class HelloMessage extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

ReactDOM.render(
  <HelloMessage name="John" />,
  document.getElementById('container')
);

JSのなかにXMLみたいな感じでタグを書けるJSXっていうのも特徴的かなと思います。

jQueryとかでそこらじゅうでDOM操作してわけがわからなくなる。ということがなくなってとても良いですね。

どこにつかっているのか

tech.misoca.jp

ここで紹介されている、受発注機能の画面でReactを使っております。

f:id:renya-mizuno:20170515143533p:plain

当時から機能も足されて画面もリニューアルされてだいぶ変わってますね。

この画面は上の「Misocaへ戻る」以外はすべてReactで作ってます。

またこの画面に限ってはSPA (Single Page Application)として作られており、見積書とかを開くとナウい感じで開きます。

stateの管理はReduxを使っています。

github.com

Reduxにした理由は一番使われてるのでは?という感じですかね…。

Redux DevToolsはとても助かりました。

おすすめです。

よかったこと

大きい利点はUIをコンポーネントで管理できるようになったことですね。

今までのUIの実装はなんかジェンガをやっている感じでなんとか崩さないように、みたいな印象でしたがコンポーネントで管理できるようになったので、他のコンポーネントに気を使うことが殆どなくなってよかったですね。

またJSXのお陰でそのコンポーネントがどういう見た目・DOMで、何を行うものなのかがわかりやすくなったのでよかったです。

つらかったこと

Reactはまだわかりやすいかと思うのですが、Reduxが関わってきた瞬間にわけがわからなくなってしまいつらかったです。 とくに最初はよくわからず、connectを大量に行ってしまいそのまま進めてしまっていて、再描画があらゆるところで発生してパフォーマンスが相当悪くなっていたりしてました。

またアニメーションを行おうとすると簡単にはできず厳しいことが多々ありました。

github.com

これを使うといい感じにアニメーションさせることができるのですが、CSS命名規則にBEMとかをつかっていると上手くマッチせずこのためにそこだけ特例で命名規則を捻じ曲げる必要があったりしてちょっと気持ち悪い感じがあります。

まとめ

Reactをつかうことで、jQuery等でやってたDOM操作地獄が無くなるのはとてもいい感じでした。

とはいえ天国かというとそういうわけではないので、世の中難しいなぁという感じです。

frontend-temple.connpass.com

今回はざっくり書いたのですが、上のイベントでもう少し詳しい話をしようと思いますので是非いらしてください!

採用

MisocaではReactでナウいWebアプリケーションを作っていくぞ〜!というメンバーを募集しています!

リモートワークは一つの手段

 こんにちは、Misoca開発チームの @corocn です。自動車部品メーカ、SIerを経て、joinしました。最近はfactorioというゲームに嵌り、気づいたら連休が終わっていました。

Misocaのリモート事情

 Misocaでは、場所にとらわれない働き方を推進しており、フルリモートで開発しているメンバーが多数参加しています。

 同時期にjoinしたメンバーが4人ほどいるのですが、そのうち3人がフルリモートワーク、1人(私)がオフィスワークとなりました。2017年5月現在のメンバーの居住地を地図に表してみました。

f:id:corocn:20170510182023p:plain

 愛知は本社があるため人数多めですが、バリエーション豊かになってきました。色んな地域のメンバーが増えるといいなあと思っています。*1

フルリモート前提の組織づくり

 スムーズなコミュニケーションのために、Misocaでは以下のようなツールを使っています。

  • 社内チャット: Slack
  • ビデオ/音声通話: Google Hangouts, Slack Call, Zoom, Screenhero, Skype
  • 文章化: esa
  • タスク管理:Trello

 ミーティングはGoogle Hangoutsをメインで使用し、1on1のミーティングはSlack callを使ったり、ペアプロする時はScreenheroを使ったり等状況によって使い分けていたりします。普段の会話は、Slackでワイワイやってます。

f:id:corocn:20170414161022j:plain

 オフィスにいるメンバーは、常設してある巨大ディスプレイと会議用の広範囲集音マイクを使用して参加しています。マイク感度が高いので、リモートからの挨拶に対して、自分の席から挨拶を返すことができて、同じオフィスで働いているように感じさせてくれます。

働く場所は関係なかった

 普段オフィスで働いているメンバーも、都合に合わせてリモートワーク選択できます。私も毎日オフィスにいるのですが、実は先日初めてリモートを試しました。

「いつもと変わらず仕事ができている。なんだこれは。すごいぞ。」

と嬉しくなりました。場所を変えてもいつも通り働ける。 オフィスがあるとはいえ、前提がリモートだからこそできることだなあと思いました。今後も、雨の日などはリモートで働こうと思っています。

全員オフ会

 たまには、リモートの人も含めて全員で集まろうや!ということで こちらの記事でも触れているように、オフ会が開かれました。当日は全員がオフィスに集まって、写真を撮ったり、普段リモート経由でしかやり取りしていない相手とペアプロをしました。

「リアルでは初めまして!」

という会話が面白かったです。

目的はリモートにあらず

 リモートワークを導入したぜ!で終わっていませんか?

 目的は良いプロダクトを世の中に送り出すこと、そのために個人、チームが最大のパフォーマンスを発揮できることだと思っています。

 パフォーマンスを最大化できる環境は人それぞれで、家族のそばで働くこと、地元で働くこと、逆に、自分はオフィスにいたほうが良い。なんて人もいると思います。まつもとゆきひろ氏も語っているように、「ちょうどいい」は人それぞれなんです。

「仕事があった」のが最大の理由だけど、人口が大きすぎず、小さすぎず、(私にとって)ちょうどいい感じの都市だったのが20年住み続けた理由のような気がします。それぞれの人がじぶんの「ちょうどいい」を見つけられるといいな。 私が松江にUターンした理由 – Yukihiro Matsumoto – Medium

 その選択肢の1つとして、リモートワークが選べるのが良いのではないでしょうか。

採用

Misocaでは「ちょうどいい」を大切にするエンジニアを募集しています!

*1:愛知に本社、島根に松江オフィスがあります

再ジョインしてから10ヶ月間、Misoca内で起こった事

どうも、Misoca開発チームの @snowsunny です。

昨年の7月にMisocaに再ジョインした話を書かせて貰った者です。

tech.misoca.jp

自分の都合で、4月いっぱいでまたMisocaから旅立つ事になったので、今回は再ジョインのまとめとして、10ヶ月間でMisoca内起こった事、思った事を書いていきたいと思います。

人が増えた!!🎉

10ヶ月間で一番変わったなーと思う所であり、Misoca開発チームの文化に大きく影響を与えていると思います。

昨年の7月から今年の5月までで、開発者の人数が倍近く増えています!

自分が入った時点では、オフィスにある机や椅子、モニターにも空きがあったのですが、現在はそれでは足りなくなってきて新たな机、椅子、モニターが増えました。

オフィスにくる人だけでもその状態なのですが、リモートワークで働かれる方も増え、朝会等でGoogleハングアウトを開くと右下に多くの人のカメラ映像や、アイコンが映っていて「人増えたなー」と実感しています。

新しい人達がもたらす空気はとても新鮮で、それによって社内のコミュニケーションやプロセス、コードの見直し等、色々な事がドンドン改善・修正されていきました。

Misocaに入るまでは、同じ顔ぶれの少人数でずっと開発をする事が多かった自分としては、とても楽しい体験でした。

プロジェクトの概念の導入

これが導入されるまで、Misocaでは開発チーム全体での朝会や、ふりかえり、タスクの相談等を毎朝行っていたのですが、全てを一括で行っていた為、冗長に感じる事があり開発チームの中で大分負担になってきていました…。

そこで大きな目標に合わせて細分化された、プロジェクトと言う概念が導入されました!

プロジェクト毎に朝会やふりかえり、相談を行う事で、冗長に感じる時間を無くし、ミーティングの時間を大幅に縮小する事ができました。

前述の人が増えた事によって出来る事が増え、現在Misocaでは開発だけで4つのプロジェクトが同時進行しています。

この概念はずっと生き続けていて、現在のMisocaの開発には必要不可欠な物になっています!

詳しくは下記の記事をご覧下さい。

tech.misoca.jp

スクラム開発の実践

プロジェクトに分かれた事で、開発プロセスとして新たな試みを行いやすくなり、受発注プロジェクトで試験的に始まったのがスクラム開発でした。

前職でスクラム開発を行っていた人が居て、その人を中心にやり方が整備されて皆で実践していった感じです。

具体的には全員でプランニングポーカーでストーリーポイントを見積もって、スプリントのベロシティーを計測してバーンダウン&アップチャートを作って進捗確認をしたり、スプリントレビューで成果を振り返ったりしています。

最初は受発注プロジェクトだけで使われていた手法だったのですが、受発注でのノウハウが開発チームに共有され、現在は他のプロジェクトでもそのプロジェクトに合った方法に変えながらスクラム開発が行われる様になってきました。

こう言う新しい実験的な試みをドンドンやらせて貰えるMisocaの開発環境は本当に素晴らしいなーと思います!

自分としては「スクラム開発」って言う名前だけは知っていたのですが、実際に使ってみた事は無くとても新しい体験でした。 特にプランニングポーカーでの見積もりで全員の認識の齟齬を無くしたり、バーンダウン&アップチャートを作って進捗確認するのはとても分かり易く良いやり方だと思うので、Misocaを出た後の仕事でも是非活かしていきたいな思っています!

その他

  • Ruby会議のスポンサー参加
  • Ruby biz大賞受賞
  • 一つの終わりと新たな始まり
  • 弥生からの友
  • Misocaボードゲーム
  • 受付水漏れ騒動
  • 自動ドア粉砕事件
  • 初めてのゴルフ場 雨のち晴れ

等々、他にも色々あったですが、それはまた別の機会に。

まとめ

再ジョインして10ヶ月経ちましたが、その10ヶ月間で、Misocaの開発プロセスや環境は大きく変わっています。 もう最初にどんな感じで開発を進めていたのかハッキリ思い出せないくらいです…w

そしてその変化は良くなる為の物であり、Misocaは現在進行系で変化し続けています。 1年後くらいのMisocaの開発環境は、また大きく違うより良いものになっているんだろうなーと確信しています。

こう言う変化を続けるMisocaで働けたのは、開発者としてとても楽しく、とても良い経験になりました。

5月からMisocaを離れるのですが、Misocaで得られた経験を活かして違う仕事に邁進していこうと思います!💪

Misocaの皆様へ

再ジョインしてからの10ヶ月間、ご迷惑をおかけする事も多かったと思うですが、色々な経験をさせて頂いて感謝の念でいっぱいです。

またどこかでお会いする機会があったら仲良くしてやって下さい。

本当にありがとうございましたー! 👋 😊

村上春樹のうなぎ説を応用して、Misocaうなぎ説でチームづくりに取り組む

ユーザー、プロダクト、チーム

こんにちは、こくぼ @ です。 プロダクトをつくることと、つくりかたをデザインすることが好きです。

早速ですが、プロダクトをつくる流れをごくごく簡単にまとめてみました。 f:id:yusuke-k:20170424144635p:plain

細かいことを言うと、他にもプロダクトのリリースに至るまでのプロジェクトについての話があったり、リリース後のユーザーサポートやメトリクスの話があったりしますが割愛します。

今日はチームづくりの話をします

f:id:yusuke-k:20170426133251p:plain

よいプロダクトはよいチームによってつくられます。 よいチームをつくるためにはよいマネジメントが必要です。

ボトムアップの行動と文化は勝手には育ちません。 会社としてトップダウンで環境をつくり、指針をつくることで文化が育まれる、というのがぼくの考えです。

今日はぼくがMisocaで行っているチームづくりについてお話しします。 チーム内のコミュニケーションを活性化するために、Misocaではうなぎミーティングというものをやっています。

普段交わらない人とのコミュニケーション

数十人を超える規模の会社になると、名前も知らなければ顔もよくわからない人が出てきますよね。 そういう人とのコミュニケーションどうしてますか?

Misocaでは現在20数人のメンバーがいて、名前と顔はわかるけど、それでも日常的にかかわる人、というのは限られてきます。 何かのプロジェクトをやることになったとき、全く話したことがない人とゼロから関係をつくっていくのは大変ですよね。

ましてや、どうやって自己紹介して、どうのように相手のことを知るのか、心理的にも負担が大きいです。 そこで第三者として「うなぎ」を持ち込みます。

村上春樹のうなぎ説

f:id:yusuke-k:20170425144056p:plain

うなぎ説とは、村上春樹さんという毎年ボジョレーヌーボーの季節になるとノーベル賞を逃すことで有名な作家さんが提唱した概念です。

うなぎの話―カウンセリングの三人目のお客さん|神戸・芦屋

村上:僕はいつも、小説というのは三者協議じゃなくちゃいけないと言うんですよ。

 

柴田:三者協議?

 

村上:三者協議。僕は「うなぎ説」というのを持っているんです。僕という書き手がいて、読者がいますね。でもその二人だけじゃ、小説というのは成立しないんですよ。そこにうなぎが必要なんですよ。うなぎなるもの。

 

(略)

 

村上:いや、べつにうなぎじゃなくてもいいんだけどね(笑)。たまたま僕の場合、うなぎなんです。何でもいいんだけど、うなぎが好きだから。

 

(略)

 

柴田:それはあれですか、自分のことを書くのは大変だから、コロッケについて思うことを書きなさいっていうことですか

 

村上:同じです。コロッケでも、うなぎでも、牡蠣フライでも、何でもいいんですけど(笑)。コロッケも牡蠣フライも好きだし

 

(略)

 

村上:たとえば、柴田さんがここにあるコロッケについて原稿用紙10枚書くとする。柴田さんはただコロッケについて書いているわけであって、柴田さん自身について語っているわけじゃないんだけども、そのコロッケについての文章を読めば、柴田さんの人柄というか、世界を見る視点みたいなものが、僕にもある程度わかるわけじゃないですか

 

柴田:ええ、願わくば

 

村上:でも柴田さんが僕に向かって直接、柴田元幸とは何か、いかなる人間存在か、というような説明をはじめると、逆に柴田元幸を理解することは難しくなるかもしれない。むしろコロッケについて語ってくれた方が、僕としてはうまく柴田元幸を理解できるかもしれない。それが僕の言う物語の有効性なんですよね。

 

村上:コロッケをあいだに引き込むことによって、コロッケに何かを託すことによって、一つの立体的な風景を共有することになる。言葉ではなく、風景を共有するということが一番大事なんです。

人と人との間に「うなぎなるもの」(途中でコロッケに変わってるけど)を介在させることにより、その人の人柄がわかり、言葉だけじゃない立体的な風景を共有できる、という説です。 この話は「ナイン・インタビューズ 柴田元幸と9人の作家たち」という本での対談なのですが、これを読んだ時、村上春樹って本当に頭の良い人なんだなあ、と感心しました。 *1

Misocaうなぎ説

うなぎなるもの=プロダクト

Misocaにうなぎを持ち込むにあたり、「うなぎなるもの」を何にするのか考えました。 そして、自分たちが日々の仕事で携わっている「プロダクト」について話すのがよいのでは、という考えに至りました。 *2

f:id:yusuke-k:20170424172350p:plain

Misoca版にアレンジ

Misocaチームは小説を書くのとは違って、チーム内で多 vs 多のコミュニケーションを取るので、Misoca版にアレンジして、多人数の中で、うなぎなるものを語りあう、という形式にしました。

これは『問題解決に効く「行為のデザイン」思考法』という本で紹介されている、役職や立場を超えた部署横断で行われるワークショップから着想を得ています。

うなぎミーティング発足

目的

Misoca社内で「うなぎミーティング」を始めるにあたり、以下のように位置づけました。

f:id:yusuke-k:20170424163333p:plain

簡単に言うと

  • みんなで共通の話題でワイワイ話そうぜ!
  • 話をしたり聴いたりすることでみんなの個性を引き出そう
  • ワイワイやってコミュニケーションを活性化していこう

となります。

ミーティングの定義(フレーミング

最初にこのミーティングについて定義をしました。 話をすることを主眼においているので、それ以上の意思決定などはこの場では行いません。

普段の仕事とは違って、話すことが目的なんだよ、結果を求める場ではないだよ、というフレーミングをしました。

f:id:yusuke-k:20170424164705p:plain

手順

MisocaではTrelloを常用しているので、各自が話したいことをカードにして、みんなの前でピッチする、というやり方をしています。 そこでみんなの共感を得られたものを投票によって決めて、掘り下げて話をする、という流れになっています。

時間があるときは、投票によって選ばれたアイデアと、適当に選ばれた人が個人の主観で選んだアイデア*3の2つについて話をしています。

f:id:yusuke-k:20170424164729p:plain

やらないこと

個人の目線でフラットに話すことが大事なので、会社としてどうするか、話す内容についての優劣など、順位を付けることはやりません。 ただ、時間は限られているため、みんながみんな話したいことを話せるとは限りません。 そこは時間と効果のバランスを見てコントロールする必要があります。

Misocaでは話す内容についてはTrelloのvote機能を使って決めています。

f:id:yusuke-k:20170424164748p:plain

ポイント

「話をする」ことが大事

  • NOT 決める場
  • 少なくとも一回につき全参加者が一度は発言してもらう
  • 喋りがちの人には気もち自重してもらう

参加者がポジティブな気持ちになれることが大事

  • NOT ネガティブ
  • 一部の人が盛り上がるだけでは意味がない
  • 辛い気もちになったらワイワイできない

うなぎについて話した結果

うなぎミーティングを毎週15分ほど時間を取って、12回実施しました。 普段はTrelloを活用していますが、一度オフラインで模造紙に付箋を貼ってやってみる、ということも試しました。

(プロダクトについて話す以上、社外秘になってしまうのであんまりお見せできないのが残念です)

Trelloでやっている様子

f:id:yusuke-k:20170424173114p:plain

f:id:yusuke-k:20170427160327p:plain

f:id:yusuke-k:20170425142243p:plain

オフラインで紙に書いている様子

普段一緒に仕事しない人とグループになってワイワイ話す。 f:id:yusuke-k:20170424173500p:plain

グループで話したことをみんなの前でワイワイ話す。 f:id:yusuke-k:20170424173633p:plain

f:id:yusuke-k:20170424174831p:plain

参加者の声

始めた当初はうまくいくか不安だったのですが、思ったよりみんな積極的に話をしてくれて毎回盛り上がりました。 以下は、社内esaや日報に寄せられたコメントです。

f:id:yusuke-k:20170425113536p:plain

f:id:yusuke-k:20170425114039p:plain

f:id:yusuke-k:20170425113608p:plain

f:id:yusuke-k:20170425113645p:plain

f:id:yusuke-k:20170425113707p:plain

f:id:yusuke-k:20170425113720p:plain

f:id:yusuke-k:20170425113833p:plain

f:id:yusuke-k:20170425113437p:plain

f:id:yusuke-k:20170425113524p:plain

プロダクション

少しずつプロダクトへの反映もされるようになってきた。 具体的な成果はこれからユーザーの皆様の目にも見える形になっていくと思います。

まとめ

よかったこと

一人一人に話をしてもらうことで、その人がどういうバックグラウンドの持ち主で、どういう目線でプロダクトを見ているのかがわかるようになりました。

また、やりたいこと、できたらよいことをみんなで語ることで、その場にポジティブな空気が生まれました。 やる気やモチベーションをあげることにも効果があるんだとよい意味での発見でした。

この取組はすぐに結果が見えるものではないので、長い目で続けていければと思ってます。

これからの課題

毎回同じ話題だとダレる?

今のところ話題は尽きませんが、同じような話題が続くと食傷気味になり、ダレてきてしまうかもしれません。

そうなったときは話題を変えて、別の「うなぎなるもの」を見つけてくる必要があるかもしれません。

話したことを行動につなげていく

現状は、第一弾として話し合うことにフォーカスしました。 今後はよりアクティブな結果につなげていける話もできたらよいかな、と思ってます。

うなぎの輪を広げていく

Misocaが弥生株式会社のグループ会社になってから関係者が飛躍的に増えました。 形態や文化の異なる会社とのコミュニケーションにも有効に使えるのではないかと期待しています。

集大成

f:id:yusuke-k:20170425140516p:plain f:id:yusuke-k:20170425140316p:plain

ということで、Misocaでの集大成が無事に着地しました。 3年半の間いろんなことに取り組ませてもらったMisocaには感謝の気もちでいっぱいです。

それでは皆さん、こくぼの次回作にご期待ください。

余談

村上春樹のこういう話をたくさん読みたい人は「村上春樹河合隼雄に会いにいく」やその他のインタビュー集を読んでみるとよいでしょう。 村上春樹の小説をまだ読んだことがない人には分量的にちょうどいい「スプートニクの恋人」をオススメします。

個人的には村上春樹翻訳のティム・オブライエンがすごく好きですが、人におすすめするにはレイモンド・カーヴァーにしています。

*1:村上春樹は小説を書くよりも翻訳とかこういう対談の方が頭の良さが際立っている気がします

*2:より正確に言うと、プロダクトについて話す場をつくりたい、という課題と、チーム内のコミュニケーションを活性化したい、という課題が重なりました

*3:21世紀枠と社内では呼んでいます

設定きりわけ大作戦

Misoca開発チームの黒曜(@kokuyouwind)です。

先日秋葉原UDXで行われた技術書典2にサークル参加して情報ガールを頒布してきました。*1

本気で原稿を落としそうになりましたが、なんとか入稿できてよかったです。

f:id:kokuyouwind:20170419175003j:plain

「原稿は早めに書こう」という教訓を得た結果、この開発ブログはそこそこ早めに書き始めています。*2

🔧 環境設定について

今回は設定ファイルの話をします。

MisocaではSettingsLogicを使い、RAILS_ENVに応じて設定を切り替えられるようにしています。*3

しかしアプリケーションの成長に伴い設定ファイルが肥大化し、以下のような設定ファイルができあがっていました。

default: &default
  application: &default_application
    host_with_port: "localhost:3000"
    protocol: http
  service_a:
    host: "<%= ENV['SERVICE_A_HOST']%>"
    token: "<%= ENV['SERVICE_A_TOKEN']%>"
    user_path: /api/v1/user
    issue_path: /api/v2/issue
  # こんな感じで設定が100行くらい続く

development:
  <<: *defaults
  service_b:
    host: dev.example.com
    application_id: misoca_dev
    secret: secret_dev_b
  service_c:
    type: mock

production:
  <<: *defaults
  application: <<: *defaults_application
    host_with_port: "<%= ENV['APPLICATION_HOST_WITH_PORT']%>"
    protocol: https
  service_b:
    host: prod.example.com
    application_id: misoca
    secret: secret_prod_b
  service_c:
    type: api
    application_id: misoca
    secret: secret_prod_c
  # こんな感じで設定が50行くらい続く

こうなると、設定を追加するのも確認するのも大変になってきます。

特にしんどいのは外部サービスの設定で、

  • RAILS_ENVに関わらず、環境変数で設定を変える(service_a)
  • RAILS_ENVで切り替える(service_b)
  • 開発環境ではモックする(service_c)

など設定方法がそれぞれで変わってしまい、設定の見通しを更に悪くしています。

🔪 設定の分割

設定ファイルの肥大化を解決するため、外部サービスの設定は別ファイルに切り出していくことにしました。

service_bの設定であれば、以下のように専用の設定ファイルを読み込むコードを書いておきます。

class ServiceBSettings < Settingslogic
  source "#{Rails.root}/config/service_b.yml"
  namespace Rails.env
end

こうすると、service_b.ymlは下記のようにとてもシンプルになります。

development:
  host: dev.example.com
  application_id: misoca_dev
  secret: secret_dev_b
production:
  host: prod.example.com
  application_id: misoca
  secret: secret_prod_b

同様に、service_cの設定は以下のようになります。

development:
  type: mock
production:
  type: api
  application_id: misoca
  secret: secret_prod_c

元の設定と比べて、環境ごとの設定がわかりやすくなりましたね。

🚩 設定切り替え条件の変更

ステージングサーバと本番サーバで外部サービスの向き先を変えたい場合は、service_aのように環境変数でサーバを切り替えることになります。*4

このような設定は、SettingsLogicのnamespaceを利用して、1つの環境変数で設定項目をまとめて切り替えるようにしました。

class ServiceASettings < Settingslogic
  source "#{Rails.root}/config/service_a.yml"
  namespace ENV['SERVICE_A_ENV'] || 'development'
end

設定ファイルであるservice_a.ymlは以下のようになります。

default: &default
  user_path: /api/v1/user
  issue_path: /api/v2/issue
development:
  <<: *defaults
  host: dev.servicea.example.com
  token: token_dev
production:
  <<: *defaults
  host: servicea.example.com
  token: token_prod

こうすることで環境変数の設定が簡潔になり、各環境での設定内容をきちんと設定ファイルに記述できるようになりました。

🏗 URLの構築

上述の設定ファイルのようにホスト名とパスをそれぞれ定義した場合、URLを使う箇所で"https://#{ServiceASettings.host}#{ServiceASettings.user_path}"のようにURLを組み立てる必要が出てきます。

これは使いづらかったので、以下のように設定クラスを拡張し、*_urlに対応する設定が見つからない場合には*_pathからURLを生成して返すようにしました。

class ServiceASettings < Settingslogic
  source "#{Rails.root}/config/service_a.yml"
  namespace ENV['SERVICE_A_ENV'] || 'development'

  # *_urlが見つからず、対応する*_pathがある場合はhostを含めたフルURLを生成して返す
  def method_missing(name)
    if name =~ /_url\Z/ && host
      path_key = name.to_s.gsub(/_url\Z/, '_path').to_sym
      url = URI.join("https://#{host}/", send(path_key)).to_s
      create_accessor_for(name, url)
      url
    else
      super
    end
  end
end

これで、ServiceASettings.user_urlのようにアクセスすることができるようになります。

設定ファイルを切り分けることで、こういった各設定ごとのヘルパーも生やすことができるようになり、なかなか便利です。*5

📢 宣伝

Misocaでは設定ファイルを綺麗にしたいエンジニアを募集しています。

*1:リンク先はおためし版になってます。全文PDFはいろいろ手直しがあり、現在頒布準備中です…

*2:結局、あまり余裕のない時間に書き上がりました

*3:類似のGemにconfigなどがあります。最近だとこちらのほうが主流かもしれません。

*4:RAILS_ENVとしてstaging環境を追加する方法もありますが、環境を増やすとそれだけ複雑になるためMisocaでは行っていません。

*5:設定クラスでやるのは邪道かもしれませんが、このためだけに別のラッパークラスを作るのもなぁ… と迷った末、今回はこうしました。

❄️frozen_string_literal

こんにちは、mzpです。最近はBuckleScriptで、OCamlJavaScriptに変換して遊んでいます。

先日、Misoca開発チームでfrozen_string_literal を有効にするようにしたので、そのときの話を紹介したいと思います。

🔥有効にする前に起きたこと

Ruby 3.0からfrozen_string_literalが標準で有効になるという話もあって、一部のコードに # frozen_string_literal: true が登場するようになりました。

次第に、 # frozen_string_literal: true を書いてないと、レビューで指摘が入るようになりました。

f:id:mzp:20170411172750p:plain

f:id:mzp:20170411173000p:plain

🚓 Rubocopの設定変更

機械的にチェックできる項目をレビューで指摘するのは好きではないので、RubocopのStyle/FrozenStringLiteralCommenteを有効にし、自動でチェック・修正できるようにしました。

f:id:mzp:20170411173235p:plain

その際、既存のコードにはすべて ruboocp:disable をいれて、このルールに検知されないようにしました。

# 既存コードは frozen_string_literal: true を書いてなくても許す
%w(app lib spec config).each do |name|
  Dir["#{name}/**/*.rb"].each do |path|
    content = File.read(path, encoding: 'utf-8')
    if content !~ /\A# frozen_string_literal: true/
      File.write(path, "# rubocop:disable Style/FrozenStringLiteralComment\n" + content)
    end
  end
end

🔪Ripperによる自動書き換え

大半のファイルに rubocop:disable が書いてあるのは微妙かなと思ったので、安全に書き換えれるファイルでは frozen_string_literal を有効にするようにしました。

具体的にはRipperで全ファイルを走査して、文字列リテラルを使っていないファイルではfrozen_string_literal を有効にするようにしました。

f:id:mzp:20170411174755p:plain

require 'ripper'

class FindStringLiteral < Ripper::Filter
  def on_tstring_beg(_, data)
    data = true
  end

  def on_tstring_content(_, data)
    data = true
  end

  def heredoc_beg(_, data)
    data = true
  end
end

def string_literal?(path)
  content = File.read(path)
  FindStringLiteral.new(content).parse(false)
end

%w(app lib spec config).each do |name|
  Dir["#{name}/**/*.rb"].each do |path|
    unless string_literal?(path)
      content = File.read(path, encoding: 'utf-8')
      if content =~ %r{\A# rubocop:disable
Style/FrozenStringLiteralComment}
        File.write(path, content.gsub(/\A.*/, "# frozen_string_literal:
true"))
      end
    end
  end
end

🚀今後の予定

残ったファイルは自動では修正できないので、別の修正するたびにちょっとづつ書き直しています。ボーイスカウトルールです。

f:id:mzp:20170411175109p:plain

🔉宣伝

Misocaではコードを綺麗にしていくエンジニアを募集しています。