valid,invalid

関心を持てる事柄について

8月はOSS活動をそれなりに頑張った

過去に作った kpt-bot を omoiyari.fm で紹介いただいたのをきっかけにモチベーションが上がり、8月はOSS活動を普段より頑張ってみることにした。

lean-agile.fm

目標

  • 週1で何らかの OSS プロダクトに Pull Request を投げる
  • 20 stars ぐらい集めるような"何か"を作る
  • 毎日コードを書く

進捗

Pull Requests

8月に出した Pull Requestsは8本で、数で言えば達成できたが内容はドキュメント更新ばかりでやや物足りない。普段から息を吸うように活動してる人はやはり尊敬する…。

作ったもの

github.com

ohbarye.hatenablog.jp

20 stars 届かず無念。とはいえ仕事でも役に立つものが出来てよかった。

毎日コードを書く

Write Code Every Day... とは違うルールだけどアクティビティ上は達成できたようだ。

その他

8月中に完成しなかったけどもちょっとした gem を作ってみたり。

感想

ちょっとした修正は GitHub の Web UI 上で完結するので便利だなァと今更思うなどした。

コントリビュートできないかと粗探しをした結果、副次的にライブラリのコードをよく読むようになった。

オープンソースの粗探し(?)に慣れると業務で触るコードも粗だらけに見えてきて最近は前よりボーイスカウト的な行動もするようになった…かもしれない。

最近の英語学習と、コミュニケーションについて思ったこと

会社では以前より遥かに使う機会が増えており、プレッシャーを感じる…。

リーディング / ライティング

以前は突然 Slack でダイレクトメッセージが来ると心臓が高なったりしたが、最近は流石に即興対応できるようになってきた。

GitHub issues でのやりとりはだいぶ前に慣れたが相変わらず語彙が少ない(Grammarly を有料契約しているので英作文の傾向や語彙数が週次で定量的に把握できる)。ネイティブの同僚のコメントなどから諸々の表現を盗みつつ改善していきたい。

知っているとちょっとかっこいい小手先のテクニックみたいなのは全然学んでいないし使っていない。

リスニング

相変わらず自信が持てないので、重要な 1 on 1 の会話をするときはこんな感じでしのいでいる。

  • 初めにゆっくり話すよう頼む
  • 何回も聞き返す
  • 相手の言葉をそのまま言い返して合っているか確認する

ランチのようなランダムチャットは何が飛んで来るかわからないぶん仕事よりも難易度が高いのだが、自分から話題を振ることでいきなりコンテキストを掴むというスキルを手に入れた。

スピーキング

発音はアメリカ英語に近づけるよう努力している。これはかっこ良さとかでなく聞き手に楽をさせるためだ。

てきとうな例だけど sea と she の発音はアメリカ英語では明らかに違う([s][ʃ])のに sea をカタカナで「シー」と発音すると、聞き手の英語話者は「どっちのことを言っているんだろう」と思う。カタカナの「シ」だと [ʃ] に近いから she だと思うかもしれないし、相手は日本人だからこの音を区別できていないのだろうと思うかもしれない。

いずれにせよ聞き手に負担をかけたまま放置するのはコミュニケーションの悪手だと自分は考えている。伝わればいいとか何も言わないよりとにかく話すのが大事と言ってカタカナ英語を推す言説も聞くが、これはやりたくない。(無論「正しい英語」なんてものは存在しないので自分がどういう英語コミュニケーションをしたいか、というだけの話)

完璧は目指していないのでそんなに力を入れて練習してはいないが、単語の意味を調べる時についでに発音記号を見るとか、基本の発音をすべて知っておくぐらいのことはしている。基本の発音の練習はもっと必要。

この辺の考え方や練習の仕方は英語耳にだいぶ影響を受けた。

amzn.to

レビュー待ちの Pull Request 一覧を Slack に定期的に通知する

review 待ちの Pull Request 一覧を Slack に定期的に通知する仕組みを作ってみた。

完成品

以下の画像は朝11時 JST に自分のチームのレビュー待ちリストを表示している様。Slack の絵文字で「いまレビューしてますよ〜」「merged!」みたいな表現をするのはエンジニアしぐさだ。

f:id:ohbarye:20170826221056p:plain

private repo だと味気ない(かつ業務情報なのでモザイクだらけだ)が、public repo の PR だと Slack が自動的に展開してくれるのでよりファビュラスに見える。

2017-08-11 11 15 31

仕組み

3行で書くと…

  • review-waiting-list-bot という Slack bot が Heroku にデプロイされている*1
  • メンションされると GitHub API を叩いてプルリクエストを収集し、まとめて Slack に post する
  • 定期的に実行する仕組みは Slack のリマインダーを使う

review-waiting-list-bot

github.com

Node.js 製の Slack botフレームワークには前回作った KPT-bot 同様、 Botkit を使っている。

async / await を試してみたかったので Node version 8 にした。残念ながら Botkit が Promise に対応しておらずコールバックを色々書くハメになる*2のだが、GitHubAPI をコールするところはうまくまとめられる。

bot をコールする際に author, owner, repo を指定することができる。-repo のような表記で除外条件(exclusive)を指定することもできる。詳細は README#Usage を参照。

Slack Reminder

bot 側で定期的に post する仕組みも作れるのだがやらなかった。設定を持たないといけなくなる=ステートレスでなくなるし、Slack に慣れているチームなら reminder 機能を充分に使いこなしてくれるからだ。

ちなみに、毎朝11時にリマインドする場合は以下のようなコマンドになる。タイムゾーンはリマインダ作成者の設定に依存するようなので注意。

/remind #channel-name "@review-bot ls author:org/my-team owner:org -repo:design" every weekday at 11am

詳細は Set a reminder – Slack Help Center 参照。

反応

開発者間のミーティングで紹介↓した後、

f:id:ohbarye:20170826225525p:plain

社内の幾つかのチームで使ってくれているようだ。Slack で定期的に呼んでいるチームもあれば daily meeting の最後に手動で呼び出して情報を同期しているチームもある。

フィリピンの同僚から Pull Request を貰ったり、チームでなく個人の活動を拾い上げたりもした。

f:id:ohbarye:20170826224603p:plain

所感

開発者だけでなく Product Manager にも喜ばれたのが意外だった。開発の進捗を把握する一助になるとか。

なんにせよ思ったより使われて良かった*3というのと、社内にユーザーがいるとフィードバックがすぐに貰えてドーパミンが出ますね。

*1:free dyno でも worker プロセスが眠らずに働いているのでいつでもメンションに反応する

*2:https://github.com/howdyai/botkit/pull/278 で試みられたがずっと放置された末に author の心が折れたようだ

*3:前作の KPT-bot が思ったほど奮わなかったのでひとしお

Rails の form 内で disabled された submit ボタンを再度 enable する

form を submit する時に disabled されるボタンを re-enable するには $.rails.enableFormElements($form) を使う。

二重サブミット防止

まず、data 属性に disable_with を設定するとクリック時にボタンが disabled になり、二重 submit 防止になる。ラベルも disabled_with で指定したメッセージに置き換わる。

<%= form_for @user do |f| %>
  <%= f.submit 'Submit', data: { disable_with: 'Submitting...' } %>
<% end %>

re-enable

submit 後に画面ごとリロードするような処理ならよいのだが、submit イベントをオリジナルの処理でハンドリングしたときは disabled されたボタンを自前で元に戻してやらないといけない。

$.rails.enableFormElements($form) がそれをやってくれる。

$form = $($.rails.formSubmitSelector)

$form.on 'submit', (e) =>
  e.preventDefault()

  $.post(url, data)
    .done(navigateToNextPage)
    .fail (xhr) =>
      showAlert(xhr)
      $.rails.enableFormElements($form)

Controller spec で render_to_string の結果が empty string になる

View でちょっと頑張る必要があり Controller から render_to_string で文字列を得てから JSON に突っ込むようなエンドポイントがあるとする。

# controller/books_controller.rb

class BooksController
  # GET /book/:id
  def show
    @book = Books.find! params[:id]
    render json: { 
      book: render_to_string(:show),
      meta: @book.meta,
    }
  end
end
# view/books/show.erb

<%= extremely_decorate @book %>
<%= other_info %>

(※ 単純化すると View でやることではないのだが、現実はもっと込み入っている…)

このエンドポイントの controller spec として以下のようなテストを書くと render_to_string の結果が empty string になる。

# spec/controller/books_controller_spec.rb

describe '#show' do
  it 'returns expected JSON' do
    subject
    response_json = JSON.parse(response.body)
    expect(response_json['book']).to eq "decorated book expression"
    # got: "" で落ちる
  end
end

controller spec では通常 view を render しないので render_views を呼ぶ必要がある。

# spec/controller/books_controller_spec.rb

describe '#show' do
  render_views

  it 'returns expected JSON' do
    subject
    response_json = JSON.parse(response.body)
    expect(response_json['book']).to eq "decorated book expression"
    # It passes!
  end
end

呼ぶ位置が少し気持ち悪い気がする。

rbenv: yarn: command not found

手元の mac で突然 yarn コマンドがエラーを吐くようになった。何をしたか思い出せない…。

$ yarn
rbenv: yarn: command not found

うーん?と思いつつどこを参照しているか確認する。

$ which yarn
/Users/ohbarye/.rbenv/shims/yarn

なんで yarn がここに入っているのかわからないので消してみる。

$ rm /Users/ohbarye/.rbenv/shims/yarn

$ which yarn
/usr/local/bin/yarn

$ yarn -v
yarn install v0.27.5
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.35s.

動いた。完

行ってよかった builderscon 2017 Tokyo

builderscon - Discover Something Newに前夜祭から最終日まで参加してきた。

感想

行く前から「絶対これを聞く!!」というような目当てがあるわけではなかったが、来てみれば発表のジャンルも幅広いし、著名な海外スピーカーも来るし(同時通訳つき)、何も見つけずに帰る方が難しぞこれはという感じで楽しめた。

前夜祭のアルコール、1日目〜2日目のコーヒーやジュース飲み放題、弁当支給(どうしても日吉の飯屋行きたかったので食べなかったけど)のホスピタリティ、そして会場:慶應義塾協生館がとても綺麗でトイレ事情も完璧。環境面でも言うことなし。ノベルティのトートバッグも格好いい(余ってたので2つ入手した)。

“Discover something new” というコンセプトも良いなァと思いつつ、当事者意識や質問が湧いてくるのは “知っている領域の延長” だったりする。なので理論上は勉強すればするほど楽しめる!!

聞いた講演

各日ごとに残したメモをそのまま公開している。

特に印象に残った講演

前夜祭全般

書くことはできませんが、最高でした。特に最初のトーク「オンプレミスデータセンター撤退! - 大人のビルコン 〜撤退技術スペシャル〜(1)」が一番のお気に入り。

前夜祭通して思ったのは、成功事例の紹介も大事だが失敗した話や苦労している話も同等かそれ以上に大事だということ。失敗談を語る勉強会みたいなのはもっと増えてもいいかもしれない。(現在進行系の話や事件直後の問題は公にできないかもしれないという問題はある…)

Desktop Apps with JavaScript

Slack 社 @felixrieseberg 氏によるデスクトップアプリ開発入門的なお話。

Electron をもともと知っている人からするとあまり刺激的ではなかったかもしれないが、個人的には「こんなに簡単にたちあがるのかァ」という発見があったので良かった。デモ慣れしててすごいなぁと思った。

Electron に関しては触らずに放置していた負い目も合ったので家に帰って実際に手を動かして試してみた。

QAタイムでは Electron 絡みでなく Slack 社に関する質問をしてよいものだろうか…ともぞもぞしてたら終わってしまってちょっと後悔。

マイクロチームでの高速な新規開発を支える開発・分析基盤

グッと来たところは以下です。

データドリブンってこういうことか…。

いらないと思われる機能をガシガシ消したい引き算の気持ちは常にあるのだが、プロダクトの引き算をするのにも裏付け・論理が大事なのでその辺にも強くなっていきたい。

RDBアンチパターンリファクタリング

ベストスピーカーを受賞したトーク。会場の空気が前のめりというか、あまりの話の深さに会場全体が集中している感じだったのでこれは取るだろうな〜となんとなく思ったりしていた。

時間がかかるからこそ戦略を立ててやっていかないといけない…というのは業務でもひどく実感しているところがあり、それが以下の質問だった。

RDBアンチパターン リファクタリングについて話をしてベストスピーカー賞を取ってきた #builderscon - そーだいなるらくがき帳にも書いていただいて大感謝というほかない。早速試してみないと。

僕はMongoDBを本番で採用したことが無いけどFDWというPostgreSQLの機能がありますよってのをご紹介しました。FDWは要は他のDBのテーブルをPostgreSQL自身のテーブルのように見させる機能です。MySQLやOracleDBもあって便利なのでぜひ遊んでみて、試してみてほしいです。

Factory Class

Kickstarter で資金調達してキーボードを作ってる Jesse さんの話。

生産を依頼する工場選定に関する話題がメインだったのだが、中国工場の裏話が実話ナックルズというか、まぁとにかく"闇"という趣だった。

前日の講演 “Desktop Apps with JavaScript” で質問できなかったのをちょっと後悔していたのでこのトークでは英語で質問してみた。「中国での工場選定の他に、プログラミングやデザインでの課題はあったか?」という質問の答えが「プログラミングは本業で20年もやってるから大丈夫、助けてくれる人も多いし」という感じで強かった。

英語で質問するのはそんなに難しくなくても自分はリスニングに難ありなので回答を100%理解するのはあきらめて聞くのは同時通訳の方に頼ったりした。

帰り道で rebuld.fm に出演していた回を見つけたので今度聞いてみる。

rebuild.fm

ランチ

日吉の学生街がめちゃ懐かしかったので、申し訳ないながらも弁当をいただかずに外食した。

ハマトラ。竹炭入りの麺が黒い。昔はこってりした家系によく行っていたが今となってはあっさり塩そばを好むようになってしまった

f:id:ohbarye:20170806204724j:plain

とんかつ和栗。学生の時は無かった気がする。蒲田の有名店「檍」系らしい。林SPFポークは塩で食べるのがおすすめらしくカウンターに4種類もの塩が置いてあり、塩派にはたまらない

f:id:ohbarye:20170806204733j:plain

キャンパス

懐かしくて死にそうだった、次回も日吉だと個人的には嬉しい

f:id:ohbarye:20170806205422j:plain f:id:ohbarye:20170806205400j:plain f:id:ohbarye:20170806205413j:plain

最後に

ディズニーランド的なアレか…