こんにちは、メディアサービス開発部Webアプリケーション開発課のシゲタです。5/11~5/13に長野県松本市で開催されたRubyKaigi2023に参加してきました。RubyKaigiへの参加は今回がはじめてなので、参加してみてどうだったのか等の感想をお話しします。RubyKaigiの雰囲気が少しでも伝えられれば幸いです。
ハイレベルで刺激を得られるセッション
わかってはいましたがやはりRubyKaigiのセッションはハイレベルでした。
Ruby言語本体の仕様や機能に焦点を当てたセッションが多く、普段低レイヤーを意識する機会が少ない私にはとくにハイレベルに感じられました。
事前に予習をして仕込みを入れてきた分野の話は割と余裕を持って聞くことができましたが、あまり予習をしてこなかった分野については、何かすごいぞ!くらいで理解が止まってしまったというのが正直なところです。
これについては事前の予習が大事で、欲を言うとチュートリアルでもいいので手を動かして触ったことがある!くらいになると楽しむ余裕を持って聞くことができるセッションが増えそうだと思いました。
とはいえ理解できなかったのはそれはそれでよくて、詳細は分からずともRubyエンジニアなら知的好奇心を刺激されるテーマばかりなので、わからないなりにも楽しむことはできます。
難しいセッションは、登場したキーワードを調べてみる、紹介されたgemをGitHubで覗いてみるなどして聞いていました。これだけでも十分に学びとなりますし、面白そうだから深掘りしてみよう、今後の動向を追ってみようという次のアクションにもつながる素材をいくつも見つけることができました。セッションを通じて学びたい意欲が高まるのもRubyKaigi効果だなと感じています。
気になったセッションについて
LT
弊社の相生も登壇した5分きっかりのLTです。登壇者の方々が楽しそうに話される姿が印象的で、皆さんそれぞれが開発を楽しんでいて、OSSや組織にコントリビュートしようとする熱意に感情移入しながら聞いていました。1日目の最後のセッションだったということもあり熱い気持ちをそのままにホクホクしながら公式パーティの会場に向かったのを覚えています。
LT自体は今年復活したようですが、個人的には是非とも来年も実施して欲しいなと思っています。
Implementing "++" operator, stepping into parse.y
Rubyに++演算子を実装しようとしたお話。
魔窟と表現されることもあるparse.yに++演算子を実装するための試行錯誤がデモを交えて紹介されました。確かにRubyに++演算子ってないよなーと思っていたが、これはオブジェクト指向のセマンティクスの問題からこれまで実装されてこなかったとのこと。
実装アイデア
- ++が読み取られたら
Interger#succ
をコールするi++
の結果がレシーバーのiに代入されない
Interger#__plusplus__
を新規で実装し、++が読み取られたらInterger#__plusplus__
をコールする1++
のようにレシーバーが変数でないときにSegmentation Faultが発生して動かない- 実装の都合上、変数idが必要だが整数リテラルはこれを持っていないことが原因
- これが冒頭で述べたオブジェクト指向のセマンティクスの問題という理解
++が読み取られたら+1と同じASTを作成する
- 他の演算子との組み合わせて使う場合に評価優先度の問題から期待する結果が得られない場合がある
i = 0 i++ * 2 p i # 1を期待するが実際に返るのは2
++が読み取られたら+1をするようなシンタックスを新規実装する
最終的には4のアイディアであれば多くのユースケースをカバーした形で++演算子が動くが、一方で既存のRubyの実装を壊してしまうそうです。
+が連続しても1が加算されるというRubyの文法が壊れてしまうらしい
i = 0 i ++ 1 # => 1 i +++ 1 # => 1 i ++++ 1 # => 1
というかRubyの+演算子が連続して使用しても動くというのをはじめて知りました。
既存の実装が壊れるってもはやRubyじゃないよね?じゃあRubyと++でRuby++だね!という綺麗な流れでセッションは終了。(Ruby++ネタはRubyKaigi中に何度か耳にしましたが、本当に誰か作ってしまうのではないだろうかと思ったり思わなかったり…)
parse.yが非常に複雑なことはファイルを覗いて察しましたが、そのうち弄って遊んでみたいなあと思えたセッションでした。
Fix SQL N+1 queries with RuboCop
ISUCON攻略のためにN+1クエリを検出して自動修正するためのRuboCopのカスタムルールを作ったというお話。実際に作成されたrubocop-isucon gem
ISUCONではN+1クエリの修正は頻繁に登場するようですが、それを検出するツールにRuboCopを採用するというのに驚きました。
N+1を自動修正するための流れ
- SQL文字列をパースしてSQLのASTを取得
- ASTの取得にはgdaを使用
- しかし、gdaはSQL文の位置情報を持っていないため、RuboCopで違反箇所をマーキングして表示することができない欠点があった
- 以下のように違反箇所のマーキングができない
class C < ApplicationRecord all.order(:created_at) ^^^ Use `.order(...)`` instead of `.all.order(...)` end
- 位置情報の取得は自前で実装することで対応
SQLのASTをRuboCopで利用できるようにする
- SQLの位置情報を保持する
RuboCop::Isucon::GDA::NodeLocation
を使えば良い
- SQLの位置情報を保持する
自動修正可能なN+1クエリ検出
- 誤検知を避けるために自動修正可能なN+1クエリの検出には苦労されたそうで、検出可能なクエリの調査に2か月、自動修正に対応するまでに1か月の時間が掛かったとのこと
- 以下の条件を満たすSQLであればクエリの自動修正ができる
- SELECT文であること
- GROUP BYが使われていないこと
- 集計関数(COUNT、MAX、SUMなど)がSELECT句に使われていないこと
- UNIONやJOIN、サブクエリが使われておらず、単一のテーブルしか登場しないこと
- WHEREに指定された条件が1つであり、そのカラムは主キー、またはユニークであること
個人的に印象に残ったのはRuboCopをDBに繋ぐというアイデアです。DBに接続してスキーマ情報を取得すれば、SELECT * FROM …
のようなSQLを、SELECT句のカラムを省略しない形式に自動修正できます。登壇者のsue445さんはRuboCopをDBに繋げるとRuboCopの可能性が広がると表現されていましたが、これを聞いたときにはlinterに対する固定観念を壊されたような衝撃を受けました。
結果としてISUCONの本番で自動修正できたN+1クエリは全体の10%未満で、発表でも言われたようにISUCONは総合格闘技なのでN+1の自動修正だけで勝つというのは難しいとのことでした。
Learn Ractor
Ractorを用いてご自身のアプリケーションをリファクタリングした経験からRactorの使い所やRactorのイディオムなどのお話。
Ractorは並列処理を実現するという目的からRactor間の競合状態を避ける必要があり、オブジェクトの共有についてかなり強い制限が設けられています。
- Ractorから外のスコープにあるオブジェクトを参照できない
- 共有できるオブジェクトはimmutableオブジェクト、Ractorオブジェクト、Class/Moduleのどれか
この制限もありRactorの内側でオブジェクト指向プログラミングのようなことをするのはやはり難しいみたいです。
一方で数値計算やインメモリDBの処理と言ったOpenMP(逐次実行の一部を並列処理するための仕組み)が得意な領域はRactorのユースケースとして効果的とのこと。登壇者のSEKIさんが昨年のセッションで紹介されたポケモンカードの検索エンジンの一部をRactorを使ってリファクタリングしたところ、処理速度に3.8倍程度の向上が見られたそうです。Ractorを使うことは難しくないが、Ractorの性能を引き出すようにコード書くことはとても難しいようで、このリファクタリングには苦労されたと話されていました。
RactorはRubyにおける気になるトピックの1つなので、こうしてRactor使って処理速度が向上したという実例が聞けるのは、自分も使ってみようかなという動機づけにもなりますし、使ってみたいという人が増えるきっかけにもなるとても意義あるセッションのように思いました。
連日開催されるアフターパーティ
RubyKaigi開催期間中は連日どこかでRubyKaigiスポンサー企業様の主催でアフターパーティが開催されていました。私も1日目から最終日まで参加させていただき、多くのRubyistの方々と交流させていただきました。
話したこと
- 気になったセッションについて
- Ractor、型関連のセッションを上げている方が多い印象で「仕事で使ってみたいんですよねー」という声もあった
- Rails使ってる?
- Rails一択で、他のフレームワークを使っているよ、という事例はお話しさせていただい方には見受けられず
- どんな感じでRails使っているのか
- Railsをフロントエンド+バックエンドの複合プロジェクト(viewをERBとReactで書いているなど)として使っている方が多い
- 使っているRuby、Railsのバージョンについて
- 最新バージョンを使っているよ、という方は少なかったです。みなさん最新バージョンへの追従には苦労をされているとのこと
- 観光した?、ご飯何食べた?などなど
私はカンファレンスといえばセッションを聞くことがメインで、セッションが終わればそそくさと帰宅するものだと思っていたので、連日お酒を交えながら交流を深められる場が用意されていることには驚きました。 どのパーティも非常に盛り上がっており、RubyKaigiはRubyist同士の親睦を深める場でもあることが強く印象付けられました。
ご飯や観光など
感想
はじめてのRubyKaigi、総じて楽しかったです。
RubyKaigiのように右も左もRubyistという空間での3日間は大変貴重な経験で、日常の開発業務で得られるものとは異なる種類の刺激を得ることができました。
難しいセッションも多いですが、わからないなりにも学びはありますし、これを理解できるようになりたい!という意欲も湧いてきました。
なので、RubyKaigiに参加してみたいがまだ自分には早いかなと参加を迷っている方、不安は横に退いといて思い切って参加してみてはいかがでしょうか。現地カンファレンスでしか摂取できない栄養のようなものはあると思うので、ぜひ参加してみることをお勧めします。
最後に、ブックウォーカーではエンジニアを募集しています。興味がありましたらぜひ、ブックウォーカーの採用情報ページからご応募ください。