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

RubyKaigi 2016 参加レポート

こんにちは、黒曜(@kokuyouwind)です。
京都国際会館を撮ったら、天気が悪かったのも相まって魔王城みたいな雰囲気になってしまいました。
なんとなく鬼岩城っぽくないですか?(遊戯王や大長編ドラではなく、ダイ大のやつ)

f:id:kokuyouwind:20160915154807j:plain

というわけで、9月8日〜10日に京都国際会館で開催されていた RubyKaigi 2016 に参加してきました!

今回はMisocaがDrinkupスポンサーになったこともあり、代表取締役@toyoshiを始め10名ものメンバーが参加しました。
開催期間中は名古屋より京都にいるメンバーの方が多い状態になっていたと思います。

以下、セッションの話とドリンクアップの話に分けて、レポートをまとめていきたいと思います。

セッションについて

ほとんどの開発者は初日のOpeningから最終日のClosingまで参加していたため、「次はA会場とB会場どっち聞きに行く?」といった会話で盛り上がっていました。
(松江から来るメンバーが電車の都合で遅れたり、2日目以降の朝に数名が寝坊してKeynoteを聴き逃したりしてましたが)

今回はConcurrencyやOptimizationの話題をはじめ、良い意味でRubyらしくないセッションが多く興味深かったです。
なかでも初日にConcurrencyのセッションが集中していたため「ConcurrencyのセッションがConcurrentlyに開かれるConcurrent RubyKaigi」というジョークも飛び出していました。

一方で応用的・実践的なトピックを取り扱ったセッションは昨年より少ない印象でした。
とはいえ参考になるセッションは多く、レガシーコードをリファクタリングする話未使用コードを検出する話HTTPクライアントをAPIと疎結合にする話などは開発に取り入れやすい話題だったと思います。

さすがに3日間続けて発表を聞き続ける機会というのはそうそうないので、最終日のKeynoteなどはかなりヘトヘトになりながら聞いていました。
総じて、普段あまりかかわらない基礎的なトピックと、業務にそのまま使えそうな実践的なトピックとを両方聞くことができ、良い刺激になりました。

ドリンクアップについて

先述の通り、今回のRubyKaigiでMisocaがDrinkupスポンサーになっており、2日目の夜にMisoca主催のドリンクアップイベントを開催しました。
事前に参加者登録が必要だったのですが、早々に定員を上回る申込みをいただき、最終的には枠を増やして90人ほどの方にご参加いただきました。

f:id:kokuyouwind:20160915171606j:plain

こういったパーティーを開催するのは初めてでノウハウがなかったため、入場整理から撤収に至るまで、かなり手探りの進行になりました。
最終的にはDoorkeeperでの参加者確認がスムーズだったことや、会場のスタッフさんを始めいろいろな方の協力を得られたこともあり、スムーズに進行することができました。

また企画についてもどういったものがあると良いかを打ち合わせ、最終的に「アイコン画像ステッカーの配布」と「Misoca開発者のトーク会」を行いました。

イコン画像ステッカーの配布についてはTwitterなどでの知り合いはアイコンが分かるとコミュニケーションしやすいだろう、というアイディアです。
参加者の方からよかったというご意見をいただけましたし、個人的にもアイコンがあることで「Twitterではいつもお世話になってます」みたいな話ができたので、良い企画だったのではないかと思っています。

開発者トークについては、自分も含めたMisocaの開発者3名がステージに上がって色々話すことで、Misocaの雰囲気を知ってもらおうという企画でした。
こちらについても予想より多くの人に聞いていただき好評だったものの、歓談と並行したことや音響の問題もあり、少し聞き取りづらいなどのご意見もいただきました。
こういった課題については、次回があれば活かせていければと思います。(次回、あると良いな)

参加者の方々のご協力もあり、Misocaメンバーも参加者の方も一緒に楽しめる良いイベントになったと思います。
ご参加いただいた皆様に、この場を借りて御礼申し上げます。

なお、ドリンクアップについては代表取締役の豊吉による開催報告記事もありますので、よければご覧ください。

まとめ

自分は去年のRubyKaigiからの参加なのですが、去年に比べるとある程度Rubyに触れてからの参加となったことや、MisocaがDrinkupスポンサーとなったことから、セッション面でも交流面でも去年より得るものが多いイベントになりました。
来年のRubyKaigiも参加していきたいと思いますので、また来年会場でお会いしましょう。

…あ、来年の話をする前に、RubyWorld Conference 2016にも参加するんでした。
こちらはスポンサー出展はなく、メンバーも3名程度の参加ですが、会場でお会いする際はよろしくお願いします。

MisocaではRubyKaigiを楽しみたい開発者を募集しています!

番外編:RubyKaigi 2016 にかこつけた京都の紹介

こんにちは、実は京都府出身*1dominion525 です。 ただいま RubyKaigi 2016 で、開発メンバーの殆どは京都に来ています。

京都府 != 京都なので、ガチ京都の人からすると噴飯物*2ではあると思うのですが、一応行政区分では同一という理由で、僭越ながら知っている範囲で京都案内を書きます。

有名な場所は、ガイドブックなり情報サイトが充実しているはずなのでそちらを参照してもらうとして、あんまりメインストリームじゃない感じの紹介をします。

ので、今日は開発ブログじゃないです。

神社仏閣

本能寺

www.kyoto-honnouji.jp

最初なので有名どころです。

法華宗本門流大本山であり、明智光秀が主君・織田信長に対して起こした「本能寺の変」でよく知られています。 京都市営地下鉄東西線 京都市役所前駅 徒歩すぐでアクセスも至便です。

Google マップ

信長公廟所などもあり物故者リストに森蘭丸の名を見つけてテンション上げたりできるのですが、要注意事項としては1591年(天正19年)に移転されており、信長が炎に包まれた場所とはちょっと違ったりすることです。 はじめて知った時はちょっと騙された感があったんですが、それでも資料館には信長や秀吉による直筆の花押なども見れますし、いろいろ楽しい感じがあります。

なお、もともとの本能寺は下記の場所らしいので、地下鉄四条駅で下車して少し歩いてみるとすぐに行けるかと思います。

Google マップ

安井金比羅宮

www.yasui-konpiragu.or.jp

祇園の花見小路(石畳でいかにも祇園!みたいなところ)の南西すぐにあります。 祇園や八坂神社などに行った際についでに立ち寄れる程度には便利な場所です。

安井金比羅はいわゆる「縁切り神社」です。 とは言え、主なご利益は「病気と縁を切りたい」「悪縁と切り、良縁を結びたい」みたいに感じで基本的には前向きに解釈されます。

とはいえ、奉納されている絵馬などをを見ると様々な生々しい話が書かれていて「人の業ってつらいな」みたいな気持ちを十分すぎるほど得ることができます。 わざわざ京都まで来てつらい気持ちを集める必要もないのですが、それっぽいスポットが好きな人には必見な感じの場所です。

あと、古今の著名人が奉納した絵馬を展示している資料室的な「金毘羅絵馬館」もあります。

参考: matome.naver.jp

また近くには井伊美術館といって、日本唯一の甲冑武具の美術館があります。井伊直政の直系の子孫な方が運営されているそうです。 近く通るたびに気になってはいるんですが、中に入ったことはないのでぜひ行ってみたいなあとは思っています。

iimuseum.wixsite.com

飲食店

ミスター・ギョーザ

京都 餃子専門店 ミスター・ギョーザ 通販あります。 HOME

Google マップ

ちょう美味しい餃子屋さんです。 京都のグルメっぽいところにすごく詳しい人に教えてもらいました。

五重塔で有名な東寺教王護国寺)の近くといえば近くなんですが、結構歩きます。 のでアクセスは正直結構悪いんですが、近所の人がひっきりなしに買いに来るくらいの人気店で、実際お手頃価格でとても美味しい餃子が食べられます。 「京都一美味しい」「関西一おいしい」などの評価もありますので、ちょっと交通は不便なのですが可能ならぜひおすすめしたいところです。

また、少し東側の公園に羅城門跡があったりします。石碑があるだけで特に構造物はないんですが、所々丹塗の剥げた、大きな円柱に、蟋蟀が一匹とまっているところなどを想像するとぐっとくるので、時間に余裕があればぜひ行ってみたいところです。

「この髪を抜いてな、この髪を抜いてな、鬘かずらにしようと思うたのじゃ。」 「では、己おれが引剥ひはぎをしようと恨むまいな。己もそうしなければ、饑死をする体なのだ。」

京都観光Navi:羅城門跡

日本酒バー あさくら

tabelog.com

先述の京都のグルメにちょう詳しいひとに連れて行ってもらいました。 三条から木屋町を上ってすぐ、くらいのところにあります。

厳選された全国の銘酒が壁一面にあって選び放題な上に、銘柄に詳しくなくても好みのタイプを言えばそれにあったおすすめをいい感じに出してもらえます。

店内自体はこじんまりしていてそんなに人数は入れないのですが、美味しい日本酒と気の利いた肴で楽しい夜が過ごせるかと思います。

Bar Moonwalk

www.barmoonwalk.jp

現在は東京や横浜、大阪などにも店舗があるのですが、京都が最初のお店です。 木屋町を中心に固まって3店舗くらいあるので、どこかには入れるはず。

ポイントはチャージ400円でドリンクがすべて200円という、異常な低価格です。 何を言ってるかわかんないんですが、生ビールからショット、カクテルに至るまですべてそのお値段です。 にも関わらず、カクテル類はバーテンダーさんがちゃんと作ってくれるので、ふつうにちゃんとバーです。 オーセンティックなお店と比べるともちろんクオリティは下回ってしまいますが、お値段を考えると圧倒的なコスパです。 いくら飲んでもまだこの値段かよ、みたいな感じで圧倒的カジュアルさで注文できます。

ポップコーンが、300円なのに一人では食べきれないレベルの量出てくるので気をつけたいところです。 個人的にはスパイシーポテトフライが好きです。

また朝5時までやっているので、n次会(n>2)でも安心な感じです。 早い時間帯だと過ごし賑やかなんですが、日を回ったりするとわりと普通に落ち着きます。 ので、少人数でもうちょっと話したいのだけど、ガッツリとした店に行くのはなーみたいなタイミングで使うとたいへん捗るように思われます。

まとめ

  • 京都をぜひ楽しんでください
  • 京都人じゃないので 「京都」って言う単語使うの怖い。

ごあんない

misoca.doorkeeper.jp

RubyKaigi 2016 二日目の今日は、Misoca Drinkup があります。 多数の人に登録いただいてすでに満員となっているのですが、ご参加いただけるひとはよろしくお願いいたします。 キャンセル待ちやご参加いただけないひとは、本編中などに仲良くしてくださいませ。

また、Misocaでは積極的にメンバーを募集していますので、少しでもご興味のあるかたはお気軽にお声がけください。

www.wantedly.com

RubyKaigi 2016アルバム

あと、せっかくなので初日に撮った写真を貼っておきます。

f:id:dominion525:20160909080309j:plain とても広くて素敵な会場なのですが、そこがいっぱいになるくらいの参加者で賑わっています。

f:id:dominion525:20160909080336j:plain 国際会議対応のホールなので、通訳とか補佐の人が付いたりするようの椅子が後ろにあったりして、面白い構造になっています。

f:id:dominion525:20160909080314j:plain 基調講演はMatzがRuby3の型の話をしてました。 型についてはアノテーションですら書きたくないという強い気持ちが伝わってきました。

f:id:dominion525:20160909080318j:plain 書籍ブースが丸善さんなので、爆弾が置かれていて大変に危険でした。 参考:梶井基次郎 檸檬

f:id:dominion525:20160909080322j:plain お昼ごはんはBentoスポンサーによる素敵お弁当。むっちゃお上品でした。山椒美味しい。

f:id:dominion525:20160909080332j:plain 庭園も使えるので開放感あって素敵でした。 遠方の山が借景になっていて、会場以外の人工構造物が見えないとか、さすがという感じです。

f:id:dominion525:20160909080342j:plain パーティの乾杯はMatzが。

f:id:dominion525:20160909080346j:plain 伏見のお酒で、気の利いた銘柄のお酒が。

*1:京都市からは離れていて、海の方までは行かないくらいの、ちょうど京都府中部の山しかないところです

*2:京都の人は上品なはずなのでご飯を噴いたりはしないと思いますが

訳しました:「オブジェクト指向設計実践ガイド」

こんにちは。Misoca開発チームのtaiki-tです。

先日、本を訳したのでそのことについて書きたいと思います。訳した本は「オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方」。

原著は”Practical Object-Oriented Design in Ruby” です。

Practical Object-Oriented Design in Ruby: An Agile Primer (Addison-Wesley Professional Ruby)

Practical Object-Oriented Design in Ruby: An Agile Primer (Addison-Wesley Professional Ruby)

著者

著者はSandi Metzさんです。現在だと「Sandi Metzルール」として聞いたことがある方が多いでしょうか。

綺麗な設計を身に付けるためのSandi Metzルール | A-Listers

Rubyistであると同時に、サイクリストでもあります。本書では、その自転車が題材として取り上げられ、コード例が構築されていきます。

本書の魅力

実践的な立場から、オブジェクト指向設計について、コード例を交えて解説していきます。大まかには下記のような説明の流れになっています。

下記のような疑問を抱いている人は、読んでみると良いと思います。

  • そもそもなぜオブジェクト指向でつくるの?
  • 単一責任の原則って聞いたことあるけど、なぜ重要なの?
  • 設計のとき、どういう観点を持てば良いの?
  • 継承とコンポジションって、どっちが良いの?
  • プライベートメソッドってテストした方が良いの?
  • そもそもテストってなにをテストすると良いの?

著者の過去30年にわたる知見に基づく実践的な立場から解説されるので、実際の開発現場できっと役に立つ知識を得られます。たとえば理論的には、いつでも単一責任の原則を適用すべきです。しかし実務上そうはいかないこともあります。そういう、設計原則を破る場合についても、

  • どういう判断基準で設計原則を破るか
  • 破る場合にはどうするか
  • マシにするためにはどうするか

というような説明がされています。極めて実践的です。

どんな本であってもその一冊だけで事足りるということはなく、この本も例外ではありません。しかし、入り口として読めば、その後の探求を続けていく準備ができる一冊だと思います。

目次は オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方:書籍案内|技術評論社 をご覧下さい。

裏話

内容を紹介してくださっている記事は他にもありますし、せっかくなのであとは翻訳裏話のコラム、的なやつを書いていこうと思います。

きっかけ

RubyKaigi2014での、技術評論社のレポーターに応募したのがきっかけです。 その後、その時の担当の方に「この本訳したいんですよー」と伝え、ありがたいことに企画を社内にあげてくださいました。 すんなりと決まったわけではなく、いろいろと紆余曲折を経て、翻訳を決まりました。 これが、2015年の1月ぐらいです。

技術評論社のレポーターに応募したいきさつは、RubyKaigiのチケット買ってなくて、「Regular Ticket…」と固まっていたところに某角谷さんから「RubyKaigiの基調講演のレポート係をgihyo.jpが募集してるけど、どう?」と声をかけていただいたのでした。 そこらへんの背景についてはこちらをご覧下さい: https://www.wantedly.com/companies/misoca/employees *1

技術評論社のレポーター自体は毎年募集しているので、気軽に応募してみると良いと思います。 今年もまだ間に合う雰囲気があるので、興味のある方は是非問い合わせてみてください。 gihyo.jp,RubyKaigi 2016のイベントレポーターを募集(若干名):インフォメーション|gihyo.jp … 技術評論社

いきなり申し込みはちょっと、という方はtaiki-t (@taiki__t) | Twitterで僕に直接いろいろ聞いてください。

大変だったこと

翻訳。翻訳大変でした。一応個人的には高校卒業時ぐらいで、TOEICでいうと915ぐらいはとってたので、俺英語チョットデキル〜とか思ってました。しかし翻訳を始めてから思い知らされたのは、ほんとにちょっとしかできてなかったな、という現実です。理解して日本語に起こすというのは、また次元の異なる作業でした。

特に頭を悩まされたことの一つが、関係代名詞の訳し方(thatとかwhichとか)です。そのとき読んでいた本 (英文翻訳術) には、「関係代名詞の扱いは難しいから、こうやって訳すといいよ」という感じでいくつか事例が載っていたので、助かったと思いつつ読んでいました。しかし、その節の最後に「でも全部一律に処理できるわけじゃないから、個別の事例は各人工夫して頑張ってね」という旨の内容が書いてあり、それを読んだ日はさすがに梨汁が飛び散りました。まぁ、逆に言えば、プロの翻訳家でもずっと苦労したり悩むところなんだなぁ、と安心した記憶もあります。そんな苦労がいくつもありました。

また、1年以上も翻訳していると、さすがに翻訳スキルも上がってきます。1年前の自分が訳した文章を見ると、「こいつはいったい何を訳してるんだ?」と思ったりするわけです。ですので、また1から訳し直したり、ということもしました。このとき、僕の心の中で、この翻訳プロジェクトは「サグラダ・ファミリア」と呼ばれていました(とはいえ、完成して良かったです)。

2015年1月下旬に翻訳を開始し、終えたのが2016年8月中旬です。実に、足かけ1年8ヶ月に及ぶ長い格闘でした。準備期間のやりとりなども含めると、話をはじめて出したのが2014年9月末ですから、ほぼ2年のプロジェクトとなりました。

翻訳した感想

  • 途中、テスト書いて通ったらOKと言えるプログラミングは素晴らしいなぁと幾度も思いました。文章にもテスト書けたら良いのに
  • 今度やるときは誰かとやりたい
  • 技術翻訳は、いろいろな意味で大変。個人のスキル、気力、体力に頼らない仕組みを作っていかないと、この先やばいのでは(実際訳されてない本たくさんあるし)
  • 作業時間は平日夜と土日という感じだったので、残業がない会社でよかった!

思い返すと苦労ばかりがすぐに浮かんでしまうのですが、書店に並んでいる本の一冊一冊に、これだけ、もしくはこれ以上の手間が掛けられているのだなぁと、本を見る目も変わりました。

ほか、ブログには書き切れないこと、書けないこともたくさんあるので、いろいろ個人的に聞いてください。西日暮里.rbに定期的に出没すると思います。あとがきにも書きましたが、訳書が皆さんのお役にたてば幸いです。

そしてこの本は、今日(2016/9/2)発売です。

RubyKaigi 2016 でサイン会もやるっぽいので、よろしかったら来てくださいね。

*1:角谷さんはMisocaの技術フェロー

読みやすいRSpecを書くためのTips

こんにちは、黒曜(@kokuyouwind)です。
最近見つけた面白いポケストップは「シーサーに似た守り神(メイドインタイランド)」です。

f:id:kokuyouwind:20160822180501p:plain

PokemonGOは飽きてきて、代わりに最新作のサン・ムーンが欲しくなってきました。
アローラロコンかわいいよアローラロコン。あとミミッキュ。

さて、Misocaに入社して一年弱が経ち、RSpecの書き方にも大分慣れてきたのですが、油断すると冗長で複雑なSpecを書いてしまいがちです。
既存のSpecが複雑だと新しいexampleを追加するときにも書きづらくなってしまうため、気づいたらなるべくリファクタリングするように心がけています。

今回は、最近自分が「こういう書き方だと読みやすく保守もしやすいのではないか」と思っているRSpecの書き方について紹介していきたいと思います。

Specを記述する対象と文脈に着目して分割する

最近書くSpecでは、大体

  • Specを記述する対象のメソッド/属性について(describe)
  • そのメソッド/属性に影響を与える文脈について(context)
  • 期待される出力について(it、出力グループが複数ある場合はdescribeでまとめる)

という順序でSpecを分割して書いています。
例えば、UserモデルのSpecであれば以下のような感じです。

RSpec.describe User, type: :model do
  describe '#valid?' do
    context '妥当なユーザーのとき' do
      let(:user) { create(:user) }
      it { expect(user).to be_valid }
    end

    context '名前が空のとき' do
      let(:user) { create(:user, name: '') }
      it { expect(user).not_to be_valid }
    end
  end
end

この定義順にすることで、Specを記述する対象のメソッドが増えた場合には単純にdescribeを一つ増やし、そこに新しいメソッドのexampleをまとめるだけで済むようになります。
また、次の節で紹介するletsubjectの遅延評価を使うことで、関心事のみを記述したSpecが書きやすくなります。

let, subjectの遅延評価を使い、関心事のみを記述する

上記の例は単純な例でしたが、少し複雑な例を考えてみましょう。 請求書の合計金額を求めるメソッド(Invoice#total_price)について、以下のようなSpecがあるとします。

RSpec.describe Invoice, type: :model do
  describe '#total_price' do
    context '明細が空のとき' do
      let(:invoice) { create(:invoice, body: create(:body, items: [])) }
      it { expect(invoice.total_price).to eq(0) }
    end

    context '明細があるとき' do
      let(:invoice) {
        create(:invoice, body: create(:body, items: [ create(:item, quantity: 2, price: 50) ]))
      }
      it { expect(invoice.total_price).to eq(100) }
    end
  end
end

このような書き方では、本来着目したいitemsの定義がinvoiceの定義の中に紛れてしまっています。
こういった場合、contextの中では関心事に関する定義だけを行うようにすることで、Specの意図がわかりやすくなります。

RSpec.describe Invoice, type: :model do
  describe '#total_price' do
    let(:invoice) { create(:invoice, body: create(:body, items: items)) }
    subject { invoice.total_price }

    context '明細が空のとき' do
      let(:items) { [] }
      it { expect(subject).to eq(0) }
    end

    context '明細があるとき' do
      let(:items) { [ create(:item, quantity: 2, price: 50)] }
      it { expect(subject).to eq(100) }
    end
  end
end

invoiceはSpec全体で共有し、各 context では items の定義のみを行っています。
このようにすることで「明細があるとき」のexampleでは「数量2で価格50の明細がある」ことから「合計金額が100になる」という意図を読み取りやすくなっています。

invoiceの定義では、まだ定義処理が書かれていないitemsを使っています。
これは少し不思議ですが、RSpecletinvoiceの値が必要になるまでブロックを評価しないため、実際に式が評価されるのはsubjectを定義する式が評価された時です。
subjectの値は各example内で使われており、このタイミングではitemsが定義された後になるため、意図したとおりに動作します。
慣れないうちは分かりづらいかもしれませんが、このように「Specを記述する対象データの一部のみを差し替える」といった用途では便利なテクニックです。

Controller Specでリクエスト処理をsubjectにする

もうひとつ遅延評価が役立つ例として、Controller Specでのリクエスト処理を紹介します。
以下のような UsersController#new のSpecを考えてみます。

RSpec.describe UsersController, type: :controller do
  describe '#create' do
    context '妥当なユーザー名とパスワードの場合' do
      let(:params) { name: 'test', pass: 'pass' }
      it { expect { post :create, user: params }.to change(User, :count).by(1) }
      it do
        post :create, user: params
        expect(response).to be_ok
      end
    end

    context 'ユーザー名が空の場合' do
      let(:params) { name: '', pass: 'pass' }
      it { expect { post :create, user: params }.not_to change(User, :count) }
      it do
        post :create, user: params
        expect(response).to be_bad_request
      end
    end
  end
end

postが全てのexampleに出てきており、responseを得るためにpostしている箇所もあるため、どういった意図でSpecを書いているのかが分かりづらくなっています。

実は、postを評価した返り値はresponseになっています。
これを利用することで、以下のように書き換えることができます。

RSpec.describe UsersController, type: :controller do
  describe '#create' do
    subject { post :create, user: params }

    context '妥当なユーザー名とパスワードの場合' do
      let(:params) { name: 'test', pass: 'pass' }
      it { expect { subject }.to change(User, :count).by(1) }
      it { expect(subject).to be_ok }
    end

    context 'ユーザー名が空の場合' do
      let(:params) { name: '', pass: 'pass' }
      it { expect { subject }.not_to change(User, :count) }
      it { expect(subject).to be_bad_request }
    end
  end
end

それぞれの行が何を意図しているか、だいぶすっきりしました。
このように、Controller Specではリクエスト処理自体をsubjectにすることで「文脈に応じたリクエスト内容の差し替え」と「リクエスト処理の集約」を両立することができ、更にレスポンスの検査もsubjectで行うことができるため、Specを記述する対象が明確になります。

注意が必要な点として、subject は初回評価時にのみリクエストが実行され、以降はリクエストが実行されず値を返すだけになります。
このためchangeを検査できるのはsubjectの最初の評価時のみになります。
1つのit内で複数のモデルについて change を検査しないかぎりは問題にならないはずですが、そのようなケースでもandを使ってマッチャーを結合すれば正しく検査することができます。

# これは必ず失敗する
it {
  expect { subject }.to change(User, :count).by(1)
  expect { subject }.to change(UserHistory, :count).by(1)
}

# こう書くと意図通りに動作する
it {
  expect { subject }.to change(User, :count).by(1)
    .and change(UserHistory, :count).by(1)
}

また、「リクエストした後にデータベースに作成されたオブジェクトを検査する」など、レスポンス以外の検査が必要な場合は先にsubjectを評価する必要があります。
before { subject } といった記述をすることになりますが、本来のsubjectの使い方とは異なるため、こういったexampleが必要な場合は素直に書いたほうがいいかもしれません。

あまり凝ったことをしない

Specをシンプルに書くためのテクニックを紹介しましたが、「Specではあまり凝ったことをしない」というのも重要です。
なぜなら「SpecのSpec」はなく、バグが紛れ込んだ場合に検知することが難しいためです。

メタプログラミングは避ける

「凝ったこと」のなかでも、特にメタプログラミングを使った共通化は避けたほうが良いと考えています。
一般にメタプログラミングは「動かしてみないと正しいかわからない」部分が多く、Specによる正しさの保証がより重要になるからです。

また、メタプログラミングは基本的に書いた本人以外には理解しづらく、保守やexample追加が難しくなりがちなことも問題です。
仕様を把握するためにSpecを確認したらSpecの仕様が把握できなかった、という事態に陥る可能性があります。

shared_examplesは注意して適用する

独自のメタプログラミングに比べると shared_contextshared_examples を使った共通化は読みやすいため、活用することでSpecを読みやすく保守しやすいものにすることができます。
ただし文字列でのlook upになるため、メタプログラミングと同じくgtagsなどでのコードジャンプの恩恵が受けられず、処理を追いにくくなることには注意が必要です。 なるべく同じファイル内で定義するか、全体で使われるものはファイルの命名・配置規約を定めて見つけやすくすると良いでしょう。

また shared_examples の内部からは、呼び出し元で let した変数を参照することができます。
うまく使うことで読みやすく再利用性の高いSpecを書くことができますが、多用すると予期せぬ変数を見てしまうことになるため注意が必要です。 コメントなどで「何の変数をどういった目的で使うか」明示すると良いでしょう。

余談ですが、「メタプログラミングshared_examplesを複数定義するコードを作りspec/support以下に配置する」なんてことをした日には、利用箇所から定義箇所を見つけ出すのが非常に困難になります。
最悪デバッガーを使えば見つけ出せるとはいえ避けるようにしましょう。

まとめ

今回書いた内容は「自分が読みやすい・保守しやすい」と感じたものなので、人によっては分かりづらいと感じるものもあるかもしれません。
またSpecを記述する対象によっても適した書き方というのは変わってくると思います。
この記事が多少なりSpecを書く際の参考になれば幸いです。

MisocaではRSpecにも妥協しないエンジニアを募集しています。

Misoca開発プロセス2016年版

こんにちは、こくぼ id:yusuke-k @ です。 株式会社ファントムタイプ @ という会社をやってます。 Misoca社には2年半ほど前からお世話になってます。

開発のプロセスや生産性をあげる組織のあり方を考えるのが好きです。 最近はUIデザインをしたり、Misocaが目指すプラットフォームのUXデザイン(見習い)をしたりしています。

ここ3年ほどでMisocaはスタートアップして資金調達からexitまで行きました。 その過程で開発プロセスもいろいろ変わってきたのでここらでいちど整理したいと思います。

注意事項

ここでは開発チームに限った話を書きますが、他にもマーケティングやユーザーサポートなどのチームがあります。

チームプロフィール

  • メンバー
    • 約8人 (女性比率0%)
  • リモートワーク
    • 1~3人

こちらのメンバー紹介記事もあわせてご覧ください。

tech.misoca.jp

全体の流れ

Misocaではプロダクトの開発が以下の流れで行われます。

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

やること会議

Misocaではやること会議と呼ばれる場所でProduct Backlogのリファインメントが行われます。 この会議はMisoca経営陣と各チームから一部のメンバーが参加して今後のプロダクトについて話をします。

  • 会社やプロダクトのロードマップを更新する
    • 直近6ヶ月〜1年までの予定を更新
    • 開発に限らずマーケティングやユーザーサポートのロードマップもある
  • 会社の目標と方針を確認する
    • 会社として何を優先して取り組むのか共通認識をつくる
  • Product Backlogの優先順位付け
    • ロードマップや目標の方針に沿ってProduct Backlogを決めて、順位付けをする

Backlogの元になるアイデア(バックログアイテム)はMisocaチームの誰でも提案できます。 ユーザーからの要望や意見から上がってくることも多々あります。

スプリント

Misocaではスクラムフレームワークにして開発のイベントをつくっています。 後述しますが、スクラムガイドに書いてあることを徹底してはいません。

weekly

スプリントプランニング

  • 1週間でやることを洗い出して目標を立てます
  • 状況によってプロジェクトごとに細分化してプランニングします

全体への成果報告

  • スプリントの終わりに開発チーム以外のメンバー全員に成果を報告します
  • 動かせられるものはデモを交えます

開発プロセスふりかえり

  • やったことや成果についてふりかえりをします
  • ここでは開発プロセスの改善に限った話をします

開発チームミーティング

  • プロダクト開発を支える技術的な話をします
  • プロセスとは関係ないコードベースの改善について話をすることが多いです
  • RubyRailsやその他ライブラリの新バージョンについてなどトピックの情報交換もします

不具合ふりかえり

  • https://app.misoca.jp/ で発生した障害や不具合についてのふりかえりをします
  • 発生原因や防止策について話をします
  • 設計の問題なのか実装や仕様の問題なのか
  • 「不具合を埋め込みやすいこのコードよくないよね」みたいな話もあります

コードを埋め込んだ個人の責任が追求されることは一度もありません tech.misoca.jp

daily

朝会

朝会については過去に記事を書いてるのでこちらをご覧ください。 tech.misoca.jp

コードレビュー

Misocaではgithub.comでPull Requestによる開発をしています。 コードレビューもPRの単位で行います。 レビュー担当などは特に設けず、各自が時間をとってレビューをします。

過去、レビュータイムという時間をとってみんなでレビューしましょう、という取り組みもやっていましたが今はレビューが習慣化されたのでやっていません。

デプロイ

マージされたPRは適当なタイミングでデプロイされます。 もちろん影響の大きいデプロイは別途調整されたうえで行われます。

スクラムとの違い

スクラムフレームワークとしていますが、完全に沿っているわけではありません。 なのでMisocaは「スクラムをやっている」わけではありません。 *1

プロダクトオーナーが明確にいない

  • 会社やプロダクトのビジョンは経営陣が示す
  • プロダクトの方向性や順位付けはやること会議で決める
  • プロダクトのデザインは開発チームと外部の協力者で決める

プランニングは簡易的にしかやってない

  • いわゆるプランニングポーカー的なものはない
  • プロジェクトごとに独自の裁量で決めている

スプリントレビューがない

  • レビューではなくデモを交えた報告をしている
  • 品質保証は開発チーム内で任されている

ベロシティなどの開発チームの生産性を測るメトリクスはない

  • プロダクトとしての指標は計測して全体で共有している
  • 開発チームの成果はそれで代用できている、と考えている

プロセスを考えるうえでの個人的な意見など

プロセスの話と技術的なトピックを分けて話をする

プロダクトのコードベースの話と人やツールのプロセスの話は微妙にコンテキストが異なります。*2 なのでそれぞれは別枠として扱っています。

開発チーム内での自浄作用

技術の選定、PRのマージまでの流れ、デプロイのルール、タスクの進め方、計画のつくりかたはチーム内で完結できるのが望ましいです。 それらの一つ一つの意思決定をチーム外に仰いでいてはパフォーマンスが出せません。 誰がどの仕事をどのように進めるのかチーム内で決めます。

ミーティングは最小限 (残業は悪)

Misocaでは残業をする文化がないので定時時間内でいかに効率的に仕事をするかを求められます。*3 そのためミーティングが多くなってくると「最近多くね」という会話が出てきます。 そうなるとミーティングを短くしたり参加人数を絞ったり、ということが行われます。 朝会なんかは特に大きく変わって今の形に落ち着いています。

生産性をあげることは大事だけどプロダクトの成功のがもっと大事

開発チームという言葉が最近あまり好きではありません。開発することだけが仕事のように見えてしまうからです。 Misocaは自社プロダクトの開発をする組織です。 なので開発をするだけでなく、プロダクトのオーナーシップをすべからく全てのメンバーが持つべきです。 チームとしての生産性を上げることももちろん大事なことですがそれ以上にプロダクトが世の中の流れに適応して柔軟に変化していける方が大事です。 *4

こまめにふりかえり、軽い気持ちでトライ

Misocaチームのよい文化の一つに「なんでもやってみる」というのがあります。 大きな方針転換も小さな改善も「とりあえず試してみよう」という気持ちにみんながなります。(ならないこともたまにあります) そのためにみんなで考えてみんなで実行しています。 ここには書ききれない細かい施策によって全体の大きな流れが形成されています。

他チームとの協同

意見をくれたユーザーへの個別連絡

ユーザーの意見や要望がリリースされた場合は、意見をいただいたユーザーへ個別連絡をしています。 これは開発チームとユーザーサポートのチームが協力して行われます。

今後解決したい課題

  • プロダクトのロードマップが全員に浸透できていない
  • メンバーが増えたときにスケールしていける自信がない
  • ダイバーシティが欠如している
  • 一部のメンバーが主導しないと前に進めないことがある
  • メンバー間のスキルトランスファーをうまくやれる方法を見いだせていない
  • 中長期的なスケジューリングが下手くそ

今後の予定

  • プロダクトがあるべき姿、について話す場を設ける
    • 開発チームに限らず「Misocaをもっとよくすること」をみんなで議論する
  • 計画づくりをうまくできるようにする
    • プランニングの精度を上げる
    • ベロシティを計測して数値で話ができるようにする
  • メンバー間のスキルトランスファーを進める

まとめ

現時点のMisocaの開発プロセスについてまとめました。 まとめてみると、まだまだチームとして改善できるポイントがあるなあ、と思いました。 今後も頑張ります。

詳しい話を聞きたい人は個別にご連絡ください。

www.wantedly.com

*1:ここ重要

*2:被ることもあります

*3:このブログもそうです

*4:生産性を犠牲にしてよいエクスキューズではありません

altCSSを捨ててPostCSSで活きよう!

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

髪がだいぶもっさりしてきたのでそろそろなんとかしないとなぁと思っています。

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

この写真は先日 きたむらさんとこくぼさんで朝明渓谷に行ってきた時の写真です。

f:id:renya-mizuno:20160728160041j:plain

すごく綺麗で泳いだのですが、まぁまぁ寒かったです。

最近はポケモンGOにはまっています。
会社の入っているビルがポケストップになっていて、お昼休みに社長がルアーモジュールを置くので、 ポケモンも集まるし、社員も集まってきます。

はい。

今回はPostCSSについて書きたいと思います。

PostCSS

github.com

そもそもPostCSSとは、Node.jsで作られたCSSのパーサでASTを操作することで色々できるといったものになります。 なので、PostCSSだけ導入しても何も起きません。
各PostCSS-pluginを追加することで、出力結果に違いが出てきます。

一番有名なのは、Autoprefixerですね。

github.com

CSSを書いているとどうしてもベンダープレフィックスが必要になってくる場合があります。
それを毎回書くのはとてもつらいので、それをAutoprefixerが自動でやってくれます。

a {
    display: flex;
}

このCSS

a {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex
}

このように自動でプレフィックスをつけてくれます。

Sassで書くと

a {    
    @include display-flex;
}

のように書かないといけなくて、CSSだけの知識では書けず、またベンダープレフィックスが不要になった時に書きなおしたりする必要が出てきてしまいます。
一方PostCSSではCSSしか書いていません。そのためベンダープレフィックスが不要になったときは、PostCSSを使わないようにすればいい。 という風に機転がききます。

このようにPostCSSのいいところは基本的にCSSを書くだけで良い。と言うところだと思っています。*1

PostCSSでトランスパイル

最近はJavaScriptを書くときにBabelを使ってES2015, ES2016をトランスパイルして使おうと言うような話が多くあると思います。
ですが、CSSではそのような話は滅多に聞きませんでした。

しかし、PostCSSのおかげで次世代のCSS構文が使えるようになりました。

例えばCSS内で変数を使いたい。というようなことは多くあったと思います。そのためSass等altCSSを使用して、変数を使っていたと思います。

$hoge-color: red;

.hoge {
  color: $hoge-color;
}

上のようなコードです。
もちろんブラウザでは動きません。
ですが、W3CCSS Custom Properties for Cascading Variables Module Level 1のような書き方でも変数を扱うことが出来ます。

:root {
  --hoge-color: red;
}

.hoge {
  color: var(--hoge-color);
}

ブラウザによってはこれで動きます(http://caniuse.com/#feat=css-variables)が対応していないブラウザもあります。

そこでPostCSSです。

github.com

このプラグインを使うことで、上のコードが

.hoge {
  color: red;
}

というふうに変換されます。

以上のような次世代のCSS構文を書けるようにするプラグインが他にもたくさんあります。

プラグインPostCSS.partsというサイトがあって、そこで検索することが出来ます。
とても便利です。

個人的なおすすめプラグインnestedです。
scssみたいに&を使うことが出来るようになります。

.hoge {
  color: red;
  &_huga {
    color: blue;
  }
}

出力は

.hoge {
  color: red;
}

.hoge_huga {
  color: blue;
}

となります。

まとめ

PostCSSの利点は

  • 基本的にCSSを書くだけで良い(altCSSの独自構文等をおぼえる必要がない)。
  • 各々が小さいプラグインとしてあるので、自分に必要なものだけを選んで適用できる。

になるかと思います。

また、PostCSSはaltCSSに比べるとコンパイルが速い。という話があったりしますが、個人的には体感出来たことがないのと、 そもそも性質が違う*2ので今回は触れませんでした。

最後に、

MisocaではPostCSSでナウいアプリケーションを作りたいというエンジニアを募集しています。

www.wantedly.com

*1:もちろん導入するプラグインによってはその限りではありません。

*2:PostCSSはプラグイン入れないとパースするだけで、altCSSはパースするだけじゃない

島根合宿に行きました

こんにちは、Misoca開発チームのmzpです。 最近、またiPhoneを割りました。

先日、Misocaメンバーで島根に合宿に行ってきました。

1日目: 移動

初日は、通常業務を昼ごろで切り上げて島根へ移動しました。

f:id:mzp:20160711165003p:plain

出雲空港につくと早速、Rubyの看板が出迎えてくれるのでテンションがあがりました。

f:id:mzp:20160711165135j:plain f:id:mzp:20160711165306p:plain

空港まで島根でリモートワークしている日高(@hidakatsuya)が迎えに来てくれたので、そのまま宿泊先である中村屋さんに向いました。宿のすぐ前が海になっており、景色がとてもよかったです。

この日は移動で疲れてたこともあり、あっさりと寝ました。

二日目: 会社訪問とトビウオ漁

f:id:mzp:20160711165855j:plain

f:id:mzp:20160711165904j:plain

二日目は松江にあるファーエンドさんとNaClさんを訪問しました。

f:id:mzp:20160623142546j:plain

午後は宿に戻り、全員でMisocaの開発について思っていることを話し合いました。 今まさに困ってることは普段話をできるので、ここでは短期的には問題ないが、このままだとよくないと思っていることについて話し合いました。

主に以下のようなことについて話し合いました。

  • 日々のタスクの改善タスクの割合について
  • リモートワーク側からオフィス側に話しかけるのに心理的障壁があることについて

f:id:mzp:20160711171437p:plain

夜はトビウオ漁(アゴすくい)に挑戦しました。 ボクはほとんど掴まえることができませんでした。

3日目

f:id:mzp:20160711180639p:plain

3日目は、合宿先である島根県松江市で開催された Agile Japan 2016 島根サテライト に参加しました。Agile Japan 島根サテライトは今年で6年目の開催となるそうです。

今年の島根サテライトのテーマは「地方都市での働き方」。Misoca はGoldスポンサーとして、2つのセッションとパネルディスカッションをさせていただきました。

f:id:mzp:20160711180902j:plain

午前の部からみんなで参加して、昼は そば処 庵兵衛 というお店で蕎麦をいただき午後の部へ。写真は角谷氏が食した割子5枚。たいへんおいしかったです。

f:id:mzp:20160711180959j:plain

Agile Shimane の鶴原さんの開催挨拶で午後の部がスタート。

f:id:mzp:20160711181105j:plain

弊社代表の豊吉も、開催挨拶の中でGoldスポンサーとして挨拶。

f:id:mzp:20160711181122j:plain

最初のセッションでは地方発のスタートアップ企業としてMisocaが取り組んできたことを紹介しました。 チームとして大事にしていること、これからも大事にしていきたいことについて話をさせていただきました。

f:id:taiki-t:20160711182325j:plain

続くセッション2では、「東京・島根からリモートワークしてわかったこと」をテーマに、高山と日高がそれぞれの経験や感じたことについて発表しました。まずは高山から。

高山は、東京から名古屋に引っ越してきたという背景があります。東京と比べ、名古屋はどうしてもコミュニティが少なくなってしまうということで、いかにその少なさと向き合うか、少なさに対処するかという観点からの話をしました。

Rubyコミュニティを名古屋で作ってみた話、名古屋からリモートで東京のコミュニティを運営してみた話など、経験に基づいた発表でした。

発表後の質問タイムでは、どのようにすればコミュニティを拡大できるか、コミュニティのメンバーはどういった方なのか、などの質問が見受けられました。

f:id:hidakatsuya:20160712180818j:plain

セッション2の二番手として、日高が「リモートワークはチームでやる」というタイトルで発表しました。

日高は、合宿先であり AgileJapan 2016 島根サテライト開催地でもある島根県松江市に住んでおり、普段はフルタイムのリモート勤務を行っています。また、昨年10月に Misoca に JOIN するまでは地元松江市SIer に勤務していました。

発表では、Wantedly で Misoca の求人 を見つけたところから、県外企業である Misoca を選んだ理由と JOIN するまでの詳しい経緯、8ヶ月間のフルタイム自宅リモートワークを通じて感じた、定期的にオフラインでメンバーと一緒に働くことの大切さ、リモートを常に意識した Misoca チームのプロセス作りについて話しました。

Misoca のリモートワーク環境等については下記エントリーで詳しく紹介しています。

tech.misoca.jp

f:id:mzp:20160711181434j:plain

ライトニングトークの先頭バッターとして、奥村がMisocaの紹介を行いました。参加者の皆さんにMisocaを知っていただく良い機会になったのではないかと思います。

f:id:mzp:20160711181600p:plain

イベント後は懇親会に参加すべく「彩鮮酒楽やぁ」へ。Ruby 関係の懇親会会場としてはお馴染みらしいです。たいへん盛り上がりました。

4日目

最終日は、特に合宿ということはなく各自観光をして名古屋に帰っていきました。

ボクは出雲大社を見に行きました。

f:id:mzp:20160711171727p:plain

f:id:mzp:20160711171735p:plain

最後に

今回の合宿は松江市産業観光部および、一般社団法人松江観光協会 美保関町支部の支援のもとに開催されました。 また、訪問先の企業の皆様、今回のAgile Japan 2016 島根サテライトを主催されたAgileShimaneの皆様にも大変お世話になりました。

この場を借りてお礼申し上げます。