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

コネヒト開発者ブログ

コネヒト開発者ブログ

Slackで簡単チェック!textlint で始める文字校正Bot

f:id:fortkle:20170216212251p:plain

こんにちは! 新オフィスに移転してから毎日2缶ドクターペッパーを買うのが習慣化してきた @fortkle です。

今回はSlackで簡単に文字校正ができるBotを作ってみたのでご紹介したいと思います。

手軽に校正したい

メールやチャットだけでなく、こういったブログやissueに書く仕様など「文章を書く」シーンはたくさんあると思います。

そんなとき自分が伝えたいことを相手にちゃんと伝えることができれば良いのですが、良い文章を書くのはなかなか難しく、今も試行錯誤しています。

そこで、相手に伝えたいことがちゃんと伝わる良い文章を書くためにSlack上で簡単に試せる文字校正Botを作ってみました。

成果物

実際に見たほうが早いと思うので画像を交えてご紹介します。 ちなみに ソースコードはGithubにあげている ので参考にしてみてください。

例として以下の文章をチェックしてみたいと思います。

この文章はご存知の通り、ダミーテキストです ヽ(^o^)丿
そして、様々な、エラーチェックに、引っかかる文章になっています。そして、意味はありません。
この文章が書くのが自動ではなく手動なのが地味に大変だったところです。
いや、大変だったとはいえないこともないです。このBOTはナウでヤングなやり方で
文章をチェックすることができます。チェック結果はslackで即座に見れます。
焦ってしまうとと誤字をすることがありますよね。そんなときに便利です。

チェックするにはSlackで文字校正Botに「check」から始まるDMを送るだけです。

check
ここにチェック
したい文章を
書きます。

実際に校正した結果がこちらです。

f:id:fortkle:20170216183734g:plain

1行目:ご存知 => 用字(ご存じ)
1行目:(^o^) => 顔文字が使われています。
2行目:様々 => 用字(さまざま)
2行目:エラーチェック => 半角カタカナが使われています。
2行目:同じ接続詞が連続して使われています。
3行目:一文に二回以上利用されている助詞 "が" がみつかりました。
4行目:こともない => 二重否定()
4行目:ナウ => 死語が使われています。
4行目:ヤング => 死語が使われています。
4行目:一文に二回以上利用されている助詞 "で" がみつかりました。
5行目:することができます => 冗長表現(できます)
5行目:見れ => ら抜き(見られ)
5行目:slack => 全角英数字が使われています。
6行目:"と" が連続して2回使われています。

どうでしょうか?意外と使えそうな気がしませんか! プロが使うような有料の校正ツールに比べると指摘内容は少ないですが、このように簡単に文字校正を試すことができます。

文字校正Botのメリット

誰でも簡単に使える!

まだ個人でしか使っていませんがもし会社で使うとなった場合でも、有償の文字校正ツールと違いSlackさえあれば誰でも利用できる手軽さがあります。 また、校正したいテキストをBotにDMで投げる形なのでチャンネルを汚すことなく利用できます。

自分が用意した辞書でカスタマイズできる!

実際の校正結果の画像をよく見ていただくと分かると思いますが、「顔文字」や「死語」などの指摘があるかと思います。 これらはどちらも自分で用意したオリジナルのルールです(死語はジョークルールですよ!)。 後述する prh というツールを使うと自分が用意した辞書を使って文章を校正することが出来ます。

校正内容のメンテナンスに夢が広がる!

今回は未実装ですが、実装さえすれば文字校正をするだけでなく校正内容も管理できると思います。

たとえば ng-word add [追加したい文言]ng-word remove [削除したい文言] などCRUD操作をできるようにしておけば Slack上から簡単に、しかも非エンジニアだけで校正内容をメンテナンスすることができそうですね!

仕組みの解説

今回の文字校正Botは Botkit をベースに textlintというツールを使ってSlack上での校正を実現しています。 Botkitのセットアップが終わりBotが動いている状態からスタートし、実際に文字校正ができるようになるところまでの実装手順をご紹介します。

1. 使っているツール

textlint

textlintは、@azu さんが作っている自然言語をLintできるツールです。JavaScriptにおけるESLintのように、あらかじめ設定しておいたルールに基づいて、テキスト上の間違いや読みにくい点などを指摘してくれます。

プラガブルであることが特徴でデフォルトでは1つもルールがありません。そのため、一般公開されているルールや自分で作ったルールを組み合わせる必要があります。

一般公開されているルールは こちら(Collection of textlint rule) で確認できます。 今回は校正のルールとして下記6つを採用しました。

採用ルール

2. インストール

textlint本体とルールをnpm経由でインストールしましょう。ここではyarnを使ってインストールします。

$ yarn add textlint textlint-rule-ja-yahoo-kousei textlint-rule-prh textlint-rule-no-doubled-conjunctive-particle-ga textlint-rule-no-doubled-conjunction textlint-rule-no-doubled-joshi textlint-rule-ja-no-successive-word

3. prh で使う辞書の作成

辞書はyaml形式で下記のように書くことができます(基本的な書き方はこちら を参考にしてください)。

version: 1
rules:
  # 大文字小文字全角半角の統一
  - expected: Cookie
  # 以下と等価 正規表現には強制でgフラグが付く
  # - expected: Cookie
  #   pattern: "/[CcCc][OoOo][OoOo][KkKk][IiIi][EeEe]/g"

  # 表現の統一を図る
  - expected: デフォルト
    patterns:  ディフォルト

さて、この設定ファイルを見ると分かる通り本来prhは表記ゆれを検出するためのツールですが、「独自の辞書を作れること」「エラーメッセージを辞書毎に設定できること」の2点から今回は簡易的なNGワードチェックのために使ってみることにします。本来の用途とは異なりますが、 expected に「エラーメッセージ」を書き、 patternにエラーにしたい単語を列挙します。

version: 1 
rules: 
  # 本来、expectedには「期待される値」が書かれるべきだがtextlint-rule-prhがprhフィールドに対応していないので「エラーメッセージ」を書く 
  - expected: 死語が使われています。 
    patterns: 
      - アイアム・ソーリー、ひげそーりー
      - あたりまえだのクラッカー 
      - アベック 
      - いただきマンモス 
      - うれピー 
      - おいくら万円 
      - オッケー牧場
      - ナウ
      - ヤング
      # (略)

4. textlint の設定ファイルを作成 ( .textlintrc )

次にtextlint の設定ファイルをJSON形式で作成し、 .textlintrc という名前で保存します。 .textlintrc には読み込みたいルールと設定を記述します。

{ 
  "rules" : { 
    "no-doubled-conjunctive-particle-ga": true,
    "no-doubled-conjunction": true,
    "no-doubled-joshi": true,
    "ja-no-successive-word": true,
    "ja-yahoo-kousei": true,
    "prh": {
      "rulePaths": [
        "./dict/prh.yml"  ← ここでprhで使う辞書を読み込む
      ] 
    } 
  }
}

ja-yahoo-kouseiルールを利用するためには事前にYahoo アプリケーションIDを取得する必要があります。 詳しくはREADMEを見てみてください。

5. textlintをモジュールとして使う

公式のドキュメントを参考に実装します。 実装例としてサンプルコードを載せておきます。

import path from 'path'
import {TextLintEngine} from 'textlint'

export default function(controller) {

  const engine = new TextLintEngine({
    configFile: path.join(__dirname, '../.textlintrc'),
  })

  const formatResults = (results) => {
    let output = '```\n'
    const messages = results[0].messages
    for (let i = 0; i < messages.length; i++) {
      const msg = messages[i]
      const msgText = `${msg.line}行目:${msg.message}\n`
      output += msgText
    }
    output += '```'

    return output
  }

  controller.hears([/^check[\n\r]([\s\S]*)/], ['direct_message'], (bot, message) => {
    const msgBody = message.match[1]

    engine.executeOnText(msgBody).then(results => {
      if (! engine.isErrorResults(results)) {
        bot.reply(message, 'エラーは見つかりませんでした。')
        return
      }

      let output = ''
      output += 'エラーが見つかりました。\n\n'
      output += formatResults(results)

      bot.reply(message, output)
    })
  })
}

これで実装は完了です!簡単なのでぜひ試してみてください!

最後に

さて、今回は textlint を使った文字校正Botについてご紹介しました。

textlintはまだまだ発展途上にあるため実務でがっつり使うにはまだ少し時間がかかるかな、というのが実際に使ってみた所感です。 特に用字用語や送り仮名、誤字脱字の検出に関しては辞書ベースの検出になるためどうしても力不足であることは否めません。 Yahoo! 校正APIを使うことである程度カバーできますが、textlintのルールは誰でも簡単に作ることができるので今後そのあたりをカバーするルールが充実するといいなと思いました。

もし興味があればルール作りなどにも挑戦してみてください!よいBotライフを!

非ネットワークエンジニアが社内ネットワークを構築したときに解決した3つの課題

f:id:tatsushim:20170203145647j:plain

こんにちは!

CTOの島田(@tatsushim)です。弊社は2017年から新オフィスに移転しました!

新オフィス移転に際して、必要になってくるのが新しい社内ネットワークです。 しかし弊社にはネットワークを専門に扱うメンバーがいません。 一方で移転することを決めてから3ヶ月というタイトなスケジュールの中でオフィス移転を実現する必要があったため、 自分たちで構築することにしました。

移転前のオフィスにおける3つの課題

1. Wi-Fiがたまに切れることがある

1つのネットワーク機器にアクセスが偏ったり、周波数帯が近いWi-Fiが存在して混線していたのが原因と考えられます。

2. Wi-Fiが遅くなることがある

Kitting*1でイメージファイル等の重いファイルのダウンロードが行われると、同じWi-Fiに接続している他の端末のネット速度が遅くなっていました。

3. いちいち場所を移動する度にWi-Fiを切り替える必要があった

AirMacを利用していたのですが、ブリッジ接続が上手くいかず、会議室と執務スペースでそれぞれ別のSSID*2で運用されていたために、移動した際に接続の切り替えを忘れていてネットに接続できずイライラ・・・なんてこともありました。

3つの課題に対する解決策

1. ネットワーク機器の適切な配置と周波数帯の設定

f:id:tatsushim:20170203122130p:plain こちらの図は、弊社の実際のオフィスの見取り図の上に各ネットワーク機器とそのカバー範囲をビジュアライズしたものです。 六角形の中心がネットワーク機器で、その機器からある程度均等な距離でWi-Fi接続をカバーする形にしました。 3つの周波数帯を用い、隣接するネットワーク機器の周波数帯を同じものにしないことで混線を避けました。

また、ネットワーク機器としてはAerohiveを導入しました。 Aerohiveを選定した理由は、グループ会社で既に安定して動いていた実績があったからです。

2. Kitting用の回線を作成

用途別に、3つの回線を用意しました。

アドレス 用途
固定IP① 社内用
固定IP② Kitting
DHCP割当 ゲスト

社内用とKitting用の回線を物理的に別にすることでKitting中でも速度低下などの影響を受けない環境になりました。

3. SSIDを統一

今までは執務室がConnehito Network1, 会議室がConnehito Network2という形でSSIDが複数ありましたが、 Aerohiveのローミング機能を利用して、上記の図の機器間で1つのSSIDを共有することができました。

実際に移転してみて

年明け初日から新オフィスでの営業でしたが、始業日から通常通り業務を始めることができ、ネットワークに関するトラブルはおきていません。 会社でインターネットが快適に使えるという“あたりまえ” を無事に提供することができたことは1つの成果なのではないかなと思っています。

移転作業に関わってくださった方々へ本当に感謝

今回の移転作業は3ヶ月という短い準備期間の中でメンバーやSyn.Holdingsの方々の助けもあり無事に達成することができました。 改めて関わってくださった皆様に感謝を申し上げます。

というわけで

快適なネット環境も手に入れたのであとはユーザーのためにプロダクトに向かうだけですね!今年も愚直に、粛々と頑張ります。 島田(@tatsushim)がお送りしました。

*1:初期環境構築に必要なソフトウェアのインストール

*2:無線LANにおけるアクセスポイントの識別名

YOKOSUKA IT Campで開発合宿を行いました

こんにちは、エンジニアの安達(@ry0_adachi)です。

この度、横須賀市が実施しているYOKOSUKA IT Campに参加して開発合宿をしてきました。
すごく良かったのでそのご紹介と、作ったものを報告しようと思います。

YOKOSUKA IT Camp

都内などのIT企業に、横須賀および横須賀リサーチパーク地区の認知度を高め、
将来的に事業拠点を置く候補地の一つとして認識していただけるよう、
横須賀市が実施する事業です。

都内のIT企業がオフサイトミーティングを横須賀リサーチパークで行う場合に、
必要な環境がすべて揃った会場を無料で提供します。

引用:YOKOSUKA IT Camp (http://www.yokosukaitcamp.com/)

横須賀の事をもっと知ってもらうための施策として横須賀市が実施しており、
合宿などで使用できる会場・設備を横須賀市が提供してくれる、というものです。

参加しようと思った経緯

年末くらいに開発合宿したい!となり会場候補を挙げていたのですが、その時に候補に挙がったYOKOSUKA IT Campの補助がすごい!となって、すかさず申し込むことにしました。
そして参加可能とのお答えをいただいて日程等の調整を進めていき今回の開発合宿に至りました。

横須賀市からの補助

今回、無料で提供していただけるものは

  • 横須賀市内の移動にマイクロバス
  • 合宿会場
  • 会場の横にある食堂でのお昼ご飯
  • 会場近くのホテル1泊分

と、何ともありがたい内容でした。ざっくりですが1人1万円くらい浮いたと思います。
また、合宿時のスケジュール作りなどもほとんどをやっていただきました。

1日目

  • 11:30 集合
  • 12:00 お昼ご飯
  • 13:00 開発
  • 19:00 晩ご飯
  • 22:30 開発

エンジニア・デザイナーの計8名で金曜日から日曜日にかけて行ってきました。
迎えのバスが来てくれるので久里浜駅に集合です。

開発会場が広い

f:id:dachi023:20170130182706j:plain

とにかく広かったです、8人で使うのがもったいないくらいでした。
作業時は写真の机を1人1つ使っていたのですが、それでもスペースが余っていたので空いた机に持ち寄ったお菓子とか飲み物を置いて使いました。
開発する場所としても室内のWi-Fiは研究施設などが入っている建物なので快適な通信速度ですし、電源は床から生えていて開発するにあたってストレスみたいなものは全くなかったです。

19時まで開発したあとは飲み会をして、終わってからは会場に戻って開発したり、ホテルに行って寝たり、各自が自由な時間を過ごしました。
ちなみに会場は24時間出入りできるので夜遅くまでやったり、朝早く起きた人は会場に来て開発したりしていました。

2日目

  • 12:00 お昼ご飯
  • 20:00 晩ご飯
  • 21:00 開発・発表資料作り

2日目は昼ご飯くらいまでには起きましょう、くらいのゆるい感じでスタートです。
ひたすら開発してた記憶しかないですが、みんな結構集中してて静かだったと思います。

美味しい牡蠣と蕎麦

f:id:dachi023:20170130194111j:plain

晩御飯は会場から徒歩5分くらいのところにあったお店に行きました。牡蠣の味噌焼丼と蕎麦が美味しかったです。あと、店員のおばちゃんがお茶目でした。

食べたあとは再度開発に戻り、最終日の発表に向けて追い込みをかける姿も見受けられました。私も開発するのが楽しくてひたすらコードを書いていました。

3日目

  • 10:00 成果発表
  • 12:00 横須賀中央駅へ移動
  • 13:00 お昼
  • 14:00 解散

いよいよ最終日、成果発表です。
発表開始ギリギリまで資料を作っている人もいました。

発表の順番決め

f:id:dachi023:20170130232405p:plain

ドカベンくじ引きで発表の順番を決めることにしました。
下記の記事を参考に実装しました。ありがとうございます。

qiita.com

成果物

1. 喋って音が鳴るBot, いでよBot

金城さん(@o0h_)の発表。

Slack上で sound!番号 と打つとBotを動かしているPCから番号に応じた音楽が鳴り、
これ読んで!読んでほしいテキスト とすると読み上げてくれます。
これはMac OSのafplaysayというコマンドを利用していて、MP3やテキストを再生する、というもの。音を出すのが楽しすぎて開発合宿が終わるまでみんな遊んでました。

そしてもう1つ、 いでよ!出てきてほしいもの と打つと登録していたものが出てくる機能。
複数行、スレッドにも対応していてslackbotの上位互換的な感じで使えそうです。

2. IntelliJプラグイン, Delegated Properties

富田さん(@tommykw)の発表。

Kotilin向けIntelliJプラグインとDelegated Propertiesのお話。
プラグインはAndroidのカスタムViewをKotlinぽくクイックフィックスしてくれるという便利なもので、こちらは完成までは至らなかったものの、Kotlinのソースコードを読んだりしてかなり知見が溜まったとのこと!IDEがないと生きていけないくらいにするため自ら貢献していく、と頼りになる言葉をいただきました。

Delegated PropertiesはKotlin標準の移譲のための仕組み。
継承するのではなく移譲することで処理の肥大化を防ぎましょうというのをママリQで実際に試した、という発表でした。

3. 妊娠月別の質問を用いたユーザ分類

CTO島田さん(@tatsushim)の発表。

ユーザ行動の分析を行うための基盤構築という難易度の高そうなものにチャレンジしていました。自然言語処理を扱うコアの部分の開発をされており、最終的にはプロダクトへの導入を検討しつつ、実際に形になったタイミングでブログやイベント等で発表するぞ!ということでした。続報に期待ですね!

4. Golangでmamari CLI

私(@ry0_adachi)の発表。

Golangでmamari CLIを実装しました。Golangの構文を覚えるところから始め、ママリ用のデプロイコマンドを作ることを目標に実装。
cobraというライブラリのおかげでシンプルな実装ができました。また、今回Golangで何かを作ったのは初めてだったのですが非常に良い言語だなぁと感じ、今後も使っていこうと思いました。

あとは、余った時間で前述のくじ引きやBotとかやったことを発表。開発合宿の時間をフル活用して色々できたので満足しました。

5. IoT知育玩具

きよえし(@kiyoe_furuichi)の発表。

可愛らしいウサギとネコのボタンを押すとディスプレイが切り替わる知育玩具です。
ウサギとネコとその土台はすべて裁縫をして作ったそうです、すごい…。
今後も子供に使ってもらえるような知育玩具をいろいろ作りたいと話していました。

発表時のスライドを上げてもらいました。 speakerdeck.com

6. 対話型Bot, ゴミ収集日リマインダ

高野さん(@fortkle)の発表。

メダロットが作りたくなったとのことで、Botkitでメタビーを実装。
docomoの雑談対話APIで雑談ができるようになっていました。

また、Botkitの対話モード(Conversations)を利用してアニメ版メダロットの名シーンを再現、ゴミ収集日をリマインダーに設定してくれる機能も実装されていました。
ゴミ出しは普通に便利そうなので真似しようかなと思っております。

7. Super Manner Mixer

結城さん(@super_manner)の発表。

Web Audio APIBeeplay.jsを使ってweb上で作曲ができるツールを作成。
画面上のボタンをポチポチやるだけで曲作れるのすごいです。

JavaScriptでこう言ったライブラリがあるということを知らなかったので勉強になったのと、そもそも作曲みたいなことがweb上の技術だけでできるんだなとびっくりしました。

8. エコー写真の検索アプリ

田村さん(@Utmrer)の発表。

エコー写真を妊娠週数ごとに閲覧可能なiOSアプリの作成。
Google Vision APIや検索結果などを駆使して週数ベースでエコー写真をカテゴライズし、それをリストで表示。
このアプリは同じ週数の方はどんな写真なのか、週数が進んだ時にどうなるのか、などの悩みを解決するためのアプリです。
アプリの技術的にはRxSwiftやXLPagerTabStripなどを利用し、実装したそうです。

実際にママさん達から上がった声からこういったものを作るのがすごくママリらしいなぁ、と感じました。

発表後

f:id:dachi023:20170202093313j:plain

発表が終わってからは横須賀市街へ行ってカレーを食べたり港沿いを散歩したりしてから解散となりました。初めての海軍カレーを食べましたがとても美味しかったです!

まとめ

というわけで、コネヒト開発部の開発合宿でした。
やるに当たって気をつけたこととしては

  • 開発に集中できる環境がある
    • Wi-Fi, 黙々と作業できる環境, 誘惑してくるもの(テレビとか)がない
  • なるべく拘束時間は減らして自由に開発する時間を増やす
  • 最後に発表を入れることで少しだけプレッシャーをかける

あたりを特に大事にしました。

また、全体的な感想として横須賀は非常に良い場所でした。ご飯も美味しかったですし、合宿会場も市街からは離れた場所なので静かですごく集中して3日間を過ごせました。
みなさんもぜひYOKOSUKA IT Campで開発合宿をやってみてはどうでしょうか。旅館などで行う合宿とはまた一風違った合宿になるかもしれません。

www.yokosukaitcamp.com

Cakeboxでお手軽CakePHP

f:id:supermanner:20170110152524p:plain

皆様、こんにちは! 今一番楽しみなのは 劇場版「Fate/stay night」Heaven's Feelであると言っても過言ではないエンジニアの結城(@super_manner)です!

さて、突然ですが現在私はCakePHP3を使ってAPI開発を行っています。

本エントリを読んでくださってるみなさまは普段どのような言語、フレームワークを使用されていますか?
体感として、近年私の周りでPHPをメインに開発されている方にはLaravelを使用されている割合が高いように思います。

日頃開発を行う中で、ふと「さっくり他のフレームワークを試してみようかな」と思うことはありませんか?
私の場合は、つい最近まではLaravelをメインに開発を行っていたので、CakePHP3を使用するにあたってあまりコストを掛けずに試すことができるものをもとめていました。

本日はお手軽にCakePHP3を試してみたいなと思った際にこういうのがあるよ!と言うものをご紹介します^^

Cakeboxとは?

Cakeboxは 「Multi-framework PHP development environment.」 を掲げていて, 少し前になりますが2015年からalpha版として世の中にリリースされています。

github.com

こちらの環境構築ツールを使用すると、Vagrant上に複数のframeworkで作成した複数のアプリケーションを走らせることが可能となっています。
デフォルトではCakePHP3が選択されており、オプションとして指定してあげることにより、2.x系やLaravel 5などのアプリを作成することができます!

実際の設定

設定はすべてCakebox.yamlに記載するだけで行うことができます。非常に簡単ですね!
詳しくはこちらの公式チュートリアルを見ていただくのが一番わかり易いです。
今回私が使用した設定は下記の通りです。

vm:
  hostname: cakebox
  ip: 10.33.10.10
  memory: 2048
  cpus: 1

cakebox:
  version: dev-dev
  debug: true
  https: false

git:
  username: my_git_user_name
  email: my.mail.address@hogehoge.com

security:
  box_public_key:
  box_private_key:

synced_folders:
  - local:  Apps
    remote: /home/vagrant/Apps

apps:
  - url: mycake3.app
  - url: mylaravel.app
    options: --framework laravel

vhosts:

databases:

extra:
  - apt_packages:
    - vim
    - zsh
    - language-pack-ja

  - scripts:

特殊な設定はしていませんが、私は普段の開発環境がvimとzshなのでextraにpackageを追記しておきました。
また、ゲストマシンにログイン時、言語設定のwarningが出るのが鬱陶しかったので、日本語のランゲージパックも入れておきました。

気になった点など

先述したとおり、Cakeboxは本当に簡単に設定できます。 しかしながら、幾つか設定中にうまくいかなかった部分や、迷った部分があるので共有させていただきたいと思います。

Laravelのアプリケーションが入らなかった

実ははじめに設定ファイルをいじって作ったり壊したりしている際に、時々エラーが出てLaravelを入れる部分で落ちてしまうケースがありました。
原因としてはmemory不足であったようです。 なので、Cakebox.yamlのvmセクションでmemoryの量を増やしました。
1024がデフォルトのところを2048にしています。

hostsの設定はどうなっているのか

Cakebox.yamlに特に何も設定していない場合vhostsの設定はどうなっているのかな?と思い見てみました。 *1
Cakeboxはdashboardから様々な設定を確認することができます。dashboardはデフォルトで 10.33.10.10 にアクセスするとみることができます。 最初にuserとpasswordを聞かれますが、何も入れなくて大丈夫です^^;

f:id:supermanner:20170110152847p:plain:w400 f:id:supermanner:20170110152854p:plain:w400

上図を見ていただくと、アプリケーション名をとってvhostsの設定がされているのがわかります。 実態としては /etc/nginx/nginx.conf に下記のように記載されていますので、

http {
  (中略)
        # virtual hosting
        include /etc/nginx/sites-enabled/*;
}

/etc/nginx/sites-enabled/* を見に行くと...

vagrant@cakebox:/etc/nginx/sites-available$ ls
default  mycake3.app  mylaravel.app

アプリケーションの名前で設定ファイルが作られていることが確認できました!
至れり尽くせりですね(^^)

感想・おわりに

業務で必要になった等で本格的に使用していく前にさっくりと新しいフレームワークを試したい場合等に、環境構築は意外と面倒なものだったりします。
今回ご紹介したCakeboxを使用すれば例えば慣れ親しんだLaravel製アプリケーションを動かしながら、CakePHP3で書いてみるとどうなるのだろうと言った使い方が可能です。

Cakeboxはまだまだ開発途中のようなので、私もなにかしらで貢献して行きたいなと思います。 そしてCakePHPユーザーが周りに増えてくれれば知見も溜まっていいぞ!!!と心のなかで思っています。

*1:各アプリケーションにアクセスするためにはローカルマシンのhostsを設定してください http://cakebox.readthedocs.io/en/latest/tutorials/creating-your-first-website/#3-update-your-hosts-file

Kotlinを導入したお話

Kotlin Java
f:id:tommy_kw:20161106193050p:plain

こんにちは!エンジニアの富田(@tommykw)です。 ママリQ Android アプリにKoltinを導入しましたので、導入方法などを紹介します。

ママリQ Android アプリ

家族の毎日の疑問や悩みを解決するママのためのQ&Aアプリです。ストアのレビューが4.5と非常に評価の高いアプリです。

なぜKotlinを導入したのか

  • Javaだと冗長、複雑になるコードもすっきり可読性が上がる
  • Swift使いのiOSエンジニアにもなじみやすい文法
  • JavaのNullPointerExceptionを駆逐できる
  • デメリットが少なかった

簡潔に安全にコードを書けるのはいいですね。Kotlinのスコープ関数やreadonlyや強力なコレクションを言語標準機能として使えるのはとても魅力的なため導入に踏み切りました。

ただメリットだけではなく、懸念点もありました。 DataBindingを利用すると真っ赤な画面での開発になり辛いです。

f:id:tommy_kw:20161107075432p:plain

KotlinとDataBindingを使っている環境であればこのような画面で開発されていると思いますが、JetBrainsのKotlin Issueでversion 1.0.5で修正となっていますね。やったね!! 今後は快適に開発が進められそうです。

導入内容について

それぞれ内容について説明します。

導入方針策定

Kotlin化については以下の基本方針を基に進めました。

  • 無理にKotlin化はしない
  • リファクタリングや新機能を実装する際にKotlin化をする
  • テストはKotlinで書いてみる

コネヒトは開発者の人数も少なくリソースが限られているため、無理にKotlin化するのではなく、リファクタリングなど最低限の部分でKotlinを導入しています。

Kotlin version 1.0.4

Kotlinをプロジェクトに導入するのは非常に簡単です。 Android Studio > Tools > Kotlin > Configure Kotlin in Projectをクリックすればダイアログが出て、OKを押すとセットアップできます。コネヒトでは現在最新版のversion 1.0.4を導入しています。

kotlintest テストフレーム

ユニットテストでkotlintestを使っています。テストフレームはspekなどもありますが、kotlintestはscalatestのような記述でmatcherも豊富でこのライブラリだけで簡単にテストが書けるため採用しました。以下はkotlintestを使ったサンプルになります。

/**
 * 日付に関するテスト
 */
class DateTest : StringSpec() {
    init {
        "Date型からyyyy年MM月dd日形式に変換する" {
            DateUtil.toDisplayString(Calendar.getInstance().apply {
                set(2016, 11, 2)
            }.time) shouldBe "2016年11月2日"

        }
        "Date型からyyyy-MM-dd形式に変換する" {
            DateUtil.toPostString(Calendar.getInstance().apply {
                set(2016, 11, 2)
            }.time) shouldBe "2016-11-2"
        }
    }
}

アノテーションを使う

JavaとKotlinが共存するプロダクトなのでKotlinからJavaを呼び出すこともありますし、その逆も然りです。クラッシュ予防や簡潔に呼び出すためのアノテーションを使いました。

  • @Nullableアノテーション
class TestActivity : AppCompatActivity(), TextView.OnEditorActionListener {
    override fun onEditorAction(v: TextView, actionId: Int, event: KeyEvent): Boolean {  // java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter event
    }
}

上記のコードはKeyEventがNonnullのため実行時にクラッシュします。これはNonnullな型に対してnullがセットされたため発生するクラッシュです。このようなクラッシュが起きた時はエラーだけを見てもどこでエラーが発生したか分かりにくいです。 この不具合を回避するためにはJava側では@Nullableアノテーション、Kotlin側では?を使ってNullableであることを宣言する必要があります

  • @JvmStaticアノテーション
// Kotlin
TestFragment : Fragment() {
    companion object {
        @JvmStatic
        fun newInstance(): TestFragment {
            return TestFragment()
        }
    }
}

// Java @JvmStaticあり
TestFragment.newInstance()
// Java @JvmStaticなし
TestFragment.Companion.newInstance()

シングルトンオブジェクトをクラス内に定義するには、companionキーワードを使い、 companion付きのオブジェクトをcompanionオブジェクトと言います。 通常はcompanionオブジェクトを介して呼び出しますが、 上記のコードはアノテーションを使うことによって直接メソッドを呼ぶことができます。

  • @JvmFieldアノテーション
// Kotlin
class Member {
    @JvmField
    var id = 0
    @JvmField
    var name = ""
}

// Java
Member member = new Member();
member.id
member.name

上記のコードはPOJOにgetter/setterを生やしてプロパティを呼び出しますが、@JvmFieldを使うことによってgetter/setterではなく直接プロパティにアクセスできます。

Kotlin/Javaでそれぞれ問題なくアクセスできるので安心して導入できますね

簡単に導入結果について

  • 1ヶ月で10%くらいはKotlin化できた
  • Kotlinリファクタリングで1、2割くらいコード行数が減った
  • コレクション操作が直感的で扱いやすかった
  • val(readonly)、var(mutable)があり、readonlyがあるので安全だった
  • 遅延初期化(lateinit/lazy)が便利だった

導入が本当に楽でした。コード行数が減ったのはスコープ関数やSAM変換を使うことによって無駄なimportも減り短く記述できたからです。 valはJavaでいうfinalに近い存在だと思いますが、valはimmutableではなくあくまでreadonlyになるのが興味深かったです。実際に使ってみてreadonlyとスコープ関数と遅延初期化は非常に便利でしたし、可読性も上がり安心してコードを書くことができました。lateinit/lazyについては以下の通りです。

  • lateinit
class TestActivity : AppCompatActivity() {
    private lateinit var binding: ActivityTestBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_test)
    }
}

lateinitは必ず初期化するけどクラス生成時に初期化できないようなケースで使用します。必ず初期化するのでNonnullであることを保証し、面倒くさいNullチェックが不要となります。

  • lazy
class TestActivity: AppCompatActivity() {
    private lateinit var binding: ActivityTestBinding
    private val header by lazy {
        DataBindingUtil.inflate<HeaderBinding>(
            layoutInflater,
            R.layout.header,
            binding.headerList,
            false
        )
    }
}

lazyは対象の変数にアクセスされた際に初期化されます。遅延初期化によって効率的に初期化され、readonlyにできるのが素敵ですね

まとめ

ママリQ AndroidにKotlinを導入したお話でした。まだ導入して1ヶ月のため理解も浅く知見も少ないですが、今後KotlinやOSSに対して何かしら貢献できればと考えています。

最近のKotlin界隈では、TornadoFXRxKotlinFXAnkoなどAndroidに限らず面白いフレームが多く刺激的ではないでしょうか。version 1.1からasync、await、yieldも導入されてますます楽しみですね!

速いらしいのでYarnを使ってみる

javascript npm yarn tool

f:id:dachi023:20161015111905p:plain

こんにちは。フロントエンジニアの安達 (@ry0_adachi) です。
最近、一気に冷え込んできたのでしっかり着込んで出かけないと痛い目を見そうです (1敗)。

さて、今回はYarnをさっくり触ってみたのでその検証と感想を書こうと思います。

Yarnとは

github.com

JavaScriptのパッケージマネージャーです。
npm, package.jsonとの互換性もあるので従来のプロジェクトでも使えます。
今の所、私の認識としては「npm installを便利にしたもの」という感じ。

メリット

  • インストールが速い
  • lockファイルによるバージョンロック
  • 絵文字が可愛い

あたりでしょうか。絵文字があるおかげでインストール中もほっこりします。
それと、重複したモジュールの整理をしたりもしてくれます。
その辺はまだそんなに触ってないので、今回は本当に速いのかどうかを検証します。

Yarnのインストール

$ npm i -g yarn

npm installとyarn installの比較

せっかくなのでキャッシュを消した状態からmamariのリポジトリで試してみます。
時間計測はtimeコマンド使ってやります。
(検証はモバイルルータ使ってやったのでそもそもがめちゃ遅いです)

npm install

$ rm -rf node_modules
$ npm cache clean
$ time npm i

real    8m1.080s
user    1m23.301s
sys     0m18.123s

遅いですね...。

Yarn

まずはキャッシュない状態から。

$ rm -rf node_modules
$ time yarn

real    3m49.978s
user    0m40.128s
sys     0m18.585s

既に速いですがさらにキャッシュありでやってみます。
Yarnでインストールすると ~/.yarn-cache にグローバルなキャッシュとして残り、
2回目以降のインストールがさらに高速になります。

↓がキャッシュありの場合の検証結果です。

$ rm -rf node_modules
$ time yarn

real    0m15.863s
user    0m10.773s
sys     0m6.903s

驚きの速さ。real timeだとnpm installに比べて7分強縮まってますね。

感想

想像以上に速かったです。CI上で使ってあげたら結構な速度改善ができそうな予感です。
まだ出たばかりなので今後に期待ですが、最初の感想としては素敵!といった感じでした。

参考

「サービス落ちたら電話で通知」を10分で実現・本番に投入する(Pingdom + Pagerduty)

こんにちは、徐々に涼しくなってきた金城@o0h_です。
最近は セブン-イレブンのアボカドとツナのチョップドサラダを食べる時にちょっと幸せを感じています。タンパク質が豊富なアボカドが美味しく摂れるのも素敵です。

さて、突然ですが皆様に於かれましては「提供しているサービスの監視」どうしていますか?
監視対象や項目・方法は色々あれど、運営として最低限防がなければいけないのは「サービスが止まっていた、利用できなくなっていた」という状況でしょうか。うっ!落ちている!! 怖いですね。
死活監視。定期的に「対象の外部からアクセスして」「レスポンスを返せる」というチェックによって、アプリケーションやらデータベースやらネットワークやら・・・というあらゆるレイヤーを一気通貫で「無事そうか」を確認する。
これが通れば「最低限動いている」、もしだめなら・・・いち早く通知を受け取りたい!

コネヒトでは、お盆休みを迎えるのを機に、監視方法を刷新し新システムの導入をしました。
実際の監視から、Slackや電話でプッシュするアラートの発報まで、とてもスムーズに稼働までもっていくことができたのでした。今回はそんな便利サービス紹介させてください。

死活監視を行うPingdom と通知・エスカレーションを行うPagerDuty です。 f:id:o0h:20131109145130j:plain

続きを読む