こんにちは! ENECHANGEで働いているishibashi(id:rubita_isi)です。
okamotoと一緒にRubyKaigi2022にオフラインで参加してきました!
Day3について書いていきます。
今回も「私がRubyKaigi 2022に参加して感じたこと」、「私が参加したセッションで話されたことの要約と感想」を主に書きます。
Day1, Day2の記事をまだご覧になっていない方はこちらも是非御覧ください。
tech.enechange.co.jp tech.enechange.co.jp tech.enechange.co.jp
error_highlight: user-friendly error diagnostics
- Speaker:Yusuke Endoh
- Slide: error_highlight: User-friendly Error Diagnostics
要約
Ruby3.1におけるerror_highlight
- Ruby3.1ではerror_higlightというエラー箇所に下線を出す機能が追加された
(以下は実際の出力例)
% ruby test.rb test.rb:1:in `<main>': undefined method `revese' for "Hello":String (NoMethodError) "Hello".revese ^^^^^^^ Did you mean? reverse reverse!
- Ruby3.1では、NameError / NoMethodErrorのみに対応していた
Ruby3.2の新機能と今回のテーマ
Ruby3.2においては、以下の新機能に対応する
- ArgumentError / TypeErrorに対応
- Railsのエラーページをサポート
今回は、新機能導入にあたって生じた問題と解決方法を紹介したい
非互換問題への対応
- Ruby3.1では
Exception#message
をオーバーライドしてerror_highlightのメッセージを表示していた - このアプローチでは、以下のように互換性の問題が生じる
- テストの互換性
- 多くのテストでは、エラーメッセージをチェックする
expect { ... }.to raise_error("foobar")
- そのため、
Exception#message
の振る舞いを変えると互換性に問題が生じる
- 多くのテストでは、エラーメッセージをチェックする
- エラーログの互換性
- 多くのエラーログでは、
#message
は1行の文字列を返却することを期待する
- 多くのエラーログでは、
- テストの互換性
Exception#detailed_message
を導入することで、問題の解決を図った
- フレームワークは
#detailed_message
を使用したいかもしれないので、修正が必要- ex.) Rackの修正パッチはマージ済
- SentryとDatadogは
#detailed_message
のサポートを約束してくれた
下線の間違いへの対応
- Rubyのエラープリンタはmessageをエスケープするので、下線の位置がずれてしまう
- 解決方法は、Rubyのエラープリンタでエスケープするのをストップするだけ
- この解決方法は約1ヶ月もの期間を要した。なぜか?
- そもそもこのエスケープは、セキュリティ上の配慮で行われていた
- ターミナルには危険なエスケープシーケンスが存在するため
ex.) ファイルを作ったり、ユーザーが入力したかのように振る舞う
- ターミナルには危険なエスケープシーケンスが存在するため
- しかし、この心配は今は不要と判断できたためエスケープをストップした
- 元になった記事がとても古く(2003年)、本来はターミナルの責任であるとも言及されていた
- 現在の主なターミナルでは、こういった危険なエスケープシーケンスはサポートしていない
Railsへのサポート
- error_highlight APIを導入することで、Railsのエラーページでerror_hightを表示できるようになった
- 修正パッチはマージ済
感想
- error_highlightの新機能でRuby3.2(とRails)がさらに便利になることを期待します!
- 新機能の追加一つで、これだけの苦労や配慮が必要になるのかと、maintainer, committerの皆さんには頭が下がる思いです
- mameさんが仰っていたように、自分が使用するフレームワークでバグを見つけたらpatchのPRを送るようにしたいです
Let's collect type info during Ruby running and automaticall
要約
何をしたのか
- Rubyの実行時の処理をトレースしてRBSを生成するrbs-dynamicを作成した
動機
- RBSファイルは書きたくないが、型の恩恵は受けたい
- 静的解析である`TypeProf`とは別のアプローチをしてみたかった
- RBSに対して関心を持ちたい / 持ってほしい
実装時のイメージ
- `TracePoint`を利用してRubyのメソッド呼び出し情報を集める
- rbsライブラリを用いて、収集したメソッドのメタ情報をRBSのデータに変換する
実際に使ってみる
2種類の使用方法がある
- Ruby上からRBSデータを生成する
RBS::Dynamic.trace_to_rbs_text { #procedures }
のブロック内で呼び出されたメソッドから生成
rbs-dynamic
コマンドで生成- 以下は、ishibashiのローカル環境で
rbs-dynamic
コマンドを実行した結果
- 以下は、ishibashiのローカル環境で
- Ruby上からRBSデータを生成する
sample.rb
class FizzBuzz def initialize(value) @value = value end def value; @value end def apply value % 15 == 0 ? "FizzBuzz" : value % 3 == 0 ? "Fizz" : value % 5 == 0 ? "Buzz" : value end end (1..20).each { FizzBuzz.new(_1).apply }
- 実行結果
rbs-dynamic trace sample.rb # RBS dynamic trace 0.1.0 class FizzBuzz private def initialize: (Integer value) -> Integer def apply: () -> (Integer | String) def value: () -> Integer @value: Integer end
RBSを自動生成する上で工夫した点
Interface型を自動で定義できるようにした
rbs-dynamic
のコマンドオプション:--use-interface-method-argument
メソッドの定義元や参照先の位置情報をRBSのコメントに埋め組むようにした
rbs-dynamic
のコマンドオプション:--show-method-location
`Symbol`型 + `Symbolの値`で型定義するようにした
- RBSでは`Symbolの値`を型として利用できる
- rbs-dynamicでは`Symbol`型 を基本としつつ、
Symbol | :hoge | :foo | :bar
のように定義するようにした rbs-dynamic
のコマンドオプション:--with-literal-type
今後の課題
- RBSファイルをどう生成するのか?(いつ? / 既存ファイルとコンフリクトしないようにするには?)
- 「動いているコードが正となる」ことのギャップ(意図しない型も動いているコードが正になる)
- 型の抽象度を上げてみる
- ex.)
class Sub1 < Base
とclass Sub2 < Base
がある時にSub1 | Sub2
をBase
と定義する、とか
- ex.)
- そもそもRBSをどう活用するのか?(`Steep`以外での活用場面)
感想
- RBSはまだまだ発展途上という感じで、様々な方が面白いチャレンジをされているのだなと思いました
- 動いているコードを解析してRBSを作成するアプローチは面白いだけでなく、示唆に富むものでした
- 実際に`TypeProf`より精緻に解析されているケースを見せていただき、感動しました
Why is building the Ruby environment hard?
要約
セッションの目的
- Ruby, RubyGems, ruby-buildのmaintainerをしている立場から、ここ最近のビルドエラーの話題を拾い、一人でもビルドエラーに時間を費やす人を減らしたい
各カテゴリから一つずつエラー例をピックアップ
Ruby: Ubuntu 22.04でビルドができない
Gem: bundled gemsがビルドできない
Ruby3.2 (予想): YJITがRustになった
ビルドエラーを乗り越えた先へ
- ソフトウェアは何もしないと壊れる
- ソフトウェアを動かす環境 (OS, ミドルウェア, ハードウェア)は絶えず変化している
- 「何もしないと壊れる」のは当然である
- ソフトウェアが変化に適応する必要がある
- OSやライブララリなどが変わった時にはまず動かしてみる
- コミュニティを活用する
- 不具合があった場合は、htts://bugs.ruby-lang.org/やGitHubの各種リポジトリで報告
- ruby-jp slackや地域ミートアップで聞いてみる
感想
- 私もご多分に洩れず環境構築に苦労した経験があるので、こういった具体的なTipsの共有は大変ありがたかったです
- 「ソフトウェアは何もしないと壊れる」は肝に銘じて日々の運用をしていきたいです
- 10月リリース予定のmacOS13.0 (Ventura)へのアップデートは慎重を期した方が良さそうです(!)
- Rubyがビルドできない、`test_process.rb`のforkのテストが動かない等の問題があったようです
- 解決の目処自体は見えていそうです(皆さんの努力に感謝・・😭)
Fast data processing with Ruby and Apache Arrow
- Speaker:Sutou Kouhei
- Slide: Fast data processing with Ruby and Apache Arrow - Kouhei Sutou - Rabbit Slide Show
要約
前提知識
-
- 列データを処理するデータ分析アプリケーションを開発するための、「言語に依存しない」ソフトウェアフレームワーク
- 「言語に依存しない」:Rubyコミュニティは、共通の実装を言語を超えて共有できる
-
- Apache ArrowのRubyバインド。GObject Introspectionに基づいている
-
- Ruby用のデータ処理ツールを提供するプロジェクト
本セッションのゴール
- データ処理でRubyを使いたいと思ってほしい
- Red Data Tools projectに参加してほしい
Rubyのデータ処理高速化の2つのアプローチ
- 別プロセスによる解決
- DB等の早いデータ処理モジュールを使用
- 同一プロセスによる解決
- 他の速い言語でコアの機能を実装
別プロセスによる解決
- 今のRubyではよくあるケースだが、レスポンスが大きい場合に問題となる
- シリアライズ・デシリアライズのコストが大きいため、送信・受信処理が遅くなる
Apach Arrowフォーマットを利用すればシリアライズ・デシリアライズのコストをほぼ0にできる
-
- gRPCベースのプロトコル
- Apache Arrowフォーマットに特化
- Apache Arrow Flight SQLは、MySQL, PostgreSQL等の既存のDBではサポートされない可能性が高い
- 新しいSQLDBやBIツールはデフォルトでFlight SQLをサポートするだろう
- 次は、Fligtht SQL用のActive Recordアダプターを実装するといいのでは?
- Red Data Toolsで開発しようぜ!
ADBC: Apache Arrow Database Connectivity
- 任意のSQL DBに接続できる高速なAPI
- Flight SQLが最速のドライバーであるが、すべてのSQL DBに同じAPIでアクセスできるのは便利
- 現在、Rubyバインディングを実装中
- Red Data ToolsでADBC用のActive Recordアダプターを開発しようぜ!
同一プロセスによる解決
- 今のRubyの使われ方だとあまりないケース
- ユースケース:ローカル・リモートストレージにあるデータ処理
高速にデータ処理ができる他の速い言語で実装されたライブラリーが必要
- 速い言語:C/C++, Rust, Julia etc
C++の場合
Apach Arrow
- Apach Arrowは計算モジュールも提供している
- RubyバインディングはRed Arrow / red-arrow
- Red Arrowベースのデータフレームもある
- Apach Arrowは計算モジュールも提供している
-
- データ分析向けのSQLiteのようなもの
- Duck DBと高速にデータ交換できれば、高速データ処理を実現できる
- Apache Arrow C data/stream interface
- 高速にデータ交換するためのC ABI
- データ分析向けのSQLiteのようなもの
低レベルのAPIは整備できた
- 高レベルのAPIを実装しようぜ!
感想
- Rubyでデータ処理を扱おう/高速化しようという試みは、他のセッションでもあったので、ホットな話題なんだなという印象を持ちました
- Apache ArrowプロジェクトのProject Management Comittee ChairであるSutouさんがRubyコミッターであることは、Ruby業界にとってとても幸運なことだと思いました
- 私自身が業務でデータ処理を扱うことはあまり想定されない気はしますが、話題としては興味深かったです
- 特にADBC用のActive Recordアダプターが開発されれば、既存のRailsプロダクトの高速化につながる可能性があります
Closing session
- 閉会式では、運営スタッフの皆さんが壇上で挨拶し、会場からは万雷の拍手が送られました。
- 私自身は初めての参加でしたが、3年ぶりのオフライン開催ということで、ベテラン参加者の皆さんは感無量という感じでした!
- 次回のRubyKaigi 2023は松本で行われるとのことです!実費でもいいので、また参加したい!
- 次回までに、Rubyコミュニティになんらかの貢献をしたいです!
- Ruby is fun!