Studyplus Engineering Blog

スタディプラスの開発者が発信するブログ

RubyKaigi 2019にPlatinumスポンサーとして参加しました!

こんちにちは、スタディプラスCTOの島田です。

スタディプラスはRubyKaigi 2019Platinum Sponsorsとして参加させて頂きました。

こちらで投稿したとおり4/18~19の3日間スポンサーブースを出展しました。
ブースでは学習記録サービス「Studyplus」にちなんで「ORB(推し Ruby Book)選抜総選挙」と銘打って、好きなRuby本の投票を実施いたしました。
RubyWorld Conference 2018での投票結果と、その時に投票頂いた方の意見を元に5つの書籍を選定しました。

選定書籍一覧 - パーフェクトRuby - プロを目指す人のためのRuby入門 - たのしいRuby - ゼロからわかる Ruby 超入門 - Ruby逆引きハンドブック

スポンサーブースにて

数量限定で準備したサコッシュでしたが多くの方に投票を頂き、あっと言う間に配布が終わってしまいました。

技術書典6にて頒布された「マンガでわかるRuby」「RubyとRailsの学習ガイド」を献本頂きました。

著者の方にサインも頂きました。

matzさんもいらっしゃいました。

3日間の投票結果はこちらになります。

感想

参加メンバーの印象に残った発表です。

島田

Pattern matching - New feature in Ruby 2.7

https://speakerdeck.com/k_tsj/pattern-matching-new-feature-in-ruby-2-dot-7 @k_tsjさんによるRuby2.7のパターンマッチングの発表。

Pattern matchingとは

  • Ruby 2.7で実験的に導入された機能
  • パターンによるマッチ処理をして、マッチした値を複数の変数に代入できる
  • case/in を利用する

構文

  • パターンが上から順番に、最初に一致するまで走査される
  • マッチしない場合はelseが実行される
  • パターンにマッチせずelseがない場合は、NoMatchingPatternErrorがraiseされる
case expr
in pattern [if|unless condition]
 ...
in pattern [if|unless condition]
 ...
else
 ...
end

設計で意識した事

  • 下位互換
  • Ruby的な文法

実装のパターンを抜粋

リテラル値を利用したパターン

case 0
  in 0
  in -1..1
  in Integer
end

_を利用したパターン

case [0,1]
in [_,_]
  :reachable
end

Pin Operator。変数の値に対してパターンマッチングを行いたい場合は^を使用

a = 0
case 1
in ^a
  :reachable
end

ASパターン

case 0
in Integer => a
  a #=> 0
end

Arrayパターン

class Array
  def deconstruct
    self
  end
end

case [0, 1, 2]
in Array(0, *a, 2)
in Object[0, *a, 2]
in 0, *a, 2
end

p a #=> [1]

Hashパターン

case {a: 0}
in a: 0
  true
end

# => true

まだ実験段階のパターンマッチですが、その幅広さにRubyの柔軟性をより広げていくものだと感じました。

花井

All bugfixes are incompatibilities

ruby trunk changesでおなじみの、@nagachikaさんによる、安定版Rubyのメンテナンスについてのお話です。 1年に1回歳をとる人間の脆弱性を念頭に、これからメンテナになる人への申し送り事項の伝達というスタイルの発表でした。 trunkからバックポートしたさいに起きた実際のバグを例に、メンテナンスのキモになる「何を取り込むか判断すること」について

  • パフォーマンス改善は不具合修正と言えばそうだが、バックポート対象にはすべきでなかった。trunkがよくなればいいだけで、安定版は安定性を損なわないようにすべきだった。
  • メソッド/定数探索周りはエッジケースも多く、文法周りは組み合わせが膨大で全てテストで網羅して事前検知するのは難しい。
  • 長い間放置されていた(気づかれていない)SyntaxErrorや、リリースした当時の状況的に使われてる量が少ないものは慌てて直さなくてもよかった。

「あるアプリケーションで困っている人がいても、もっと大きなアプリケーションを壊してしまう場合はよりユーザーが多い方を優先しなければいけないという判断をしないといけないのは心苦しい。しかし、それが安定版メンテナのお仕事なのです」 という結びの言葉が印象にのこりました。

Crystalball: predicting test failures

@p0dejeさんによるcrystalballを利用した回帰テストの選択実行について内部実装のお話とデモです。 小さな変更に対して全てのテストを実行するとどうしても時間がかかってしまうので、変更したコードに関係するテストをカバレッジベースで解析し、マッピングしたうえで変更箇所に関係しているテストだけが走るようにできるというものです。 コードの変更はもちろん、schemaファイルやFactoryBotの変更にも対応していて感動しました。セッション後にridgepoleのSchemafileにも対応してるのか聞いてみましたが、ridgepoleをご存じなくデフォルトでは対応していないとのことでした。 @p0dejeさんもGraphQL周りでやっている解決策として、自前でPredictorを書くという手があるそうなので、実際に試してみようと思いました。

Best practices in web API client development

キュアエンジニア@sue445さんによる、APIクライアント開発のベストプラクティスの紹介です。

APIクライアントの責務と、作成者(自分/他人)、公開範囲(public/private)の組み合わせによるケースごとにベストプラクティスが紹介されました。

まずAPIクライアントに作るべき機能として以下をあげています。 - パラメータの変換(型変換、スネークケース・キャメルケースの変換) - エラーコード1のラップ(サンドイッチメソッドの抽出2) - OAuth2アクセストークンの自動更新

逆に作るべきでない機能としては、 - アプリの責務である、APIレスポンスのキャッシュ - 必須や空白チェック以外のリクエストパラメータの詳細なバリデーション

をあげていました。そのほかGood Patternとして以下の7つの紹介がありました。

  • runtime dependencyをできるだけ使わない(できるだけRuby標準機能でつくる)
  • Getだけならopen-uriで十分
  • Faradayは銀の弾丸
  • CRUD全部必要なケースで有用
  • 主題を目立たせる
  • 共通で使うならインスタンス変数にしておく
  • Hash引数よりkeyword引数
  • メソッドの定義が必要なものを物語るので実装しやすい・テストしやすい
  • 新しいサービスなどで頻繁に更新されるならHashでもよい
  • パラメータオブジェクト
  • たくさんの引数を受ける場合に有効
  • パラメータオブジェクト自体のテストもかける
  • 導入基準はYARDでコメントを書きやすくなるか
  • メソッドアクセス可能なレスポンス
  • mashifyを入れえると簡単に実現可能
  • curlは万国共通
  • バグレポートしたいとき、API提供者がRubyを読めるとは限らないのでcurlでレポートを書く
  • faraday-curlを使うとラク

どの内容もすぐに使える実践的な内容であるばかりか、普段の開発でも心がけた方がいい内容も含まれており、 APIクライアント作成の知見が詰まった素晴らしい発表でした。

冨山

印象に残った講演

How to use OpenAPI3 for API developer

twitter.com committeeのOpenAPI3.0対応をしたota42yさんのお話でした.
弊社でもAPI開発の際にcommitteeを使用しており内部実装の話は大変為になりました.
committeeは抽象化されたvalidatorを用意して,OpenAPI2.0, OpenAPI3.0, JSON Schemaなど複数のスキーマに対応していて, OpenAPI3.0のスキーマを理解する部分はopenapi_parserで行っているようです.またバリデーションを行う際にはパスに対応するAPIの定義が含まれるオブジェクトを参照する必要がありここの実装にも工夫がありました.
パスの階層をノードとしたパトリシア木というデータ構造をRubyオブジェクトとして持っているという設計は階層ごとにネストしたHashで定義したり,パスを全件探索するような実装より優れていて印象に強く残りました.

Pragmatic Monadic Programing in Ruby

twitter.com こちらはjoker1007さんによるRubyでmonadをする話でした. Procは手続きを持った関数オブジェクトであるとすれば関数型言語的にかけるようにできるはずだというもので, RubyVM::ASTやTracePointなどを使って悪事を働くコードを披露しつつもスタックトレースは追えるよう実装されていたりと終始会場が賑わう楽しい発表でした.

またDay1のアフターパーティは商店街を貸し切って行われるという今までに無い形の懇親会で,商店街のあちこちで日本酒,ビール,食事などなどが提供されていて,多くの人が歩きながらお酒を飲んで談笑していたため多くの方と交流ができて楽しめました. 弊社メンバーと歩いていたらメタプログラミングRuby3の著者Paolo Perrottaがいたので一緒に写真を取っていただきました! f:id:atomiyama:20190509102457j:plain

最後に

昨年度に続きRubyKaigiの協賛をさせていただき、今回は初めてスポンサーブースの出展をさせていただきました。 ブースへは本当に多くの方に足を運んで頂き、投票への協力をしていただいた事に感謝です。

スタディプラスでは、今後もRubyコミュニティの貢献を考えております。 RubyKaigi 2020は長野県松本市という事なので、何かの形で協力を出来ればと思います。


  1. APIの通信にFaradayを使うとAPIクライアントのユーザーがFaradayを意識しないといけなくなるので、Rubyのエラーに変換するという例をあげていました

  2. 『リファクタリング:Rubyエディション』

  3. メタプログラミングRuby