rubocop:disableの集計ツールの作成を通してRustを勉強してみた

本記事は Rakuten Rakuma Advent Calendar 2022 20日目の記事です。 Rustを勉強しながらrubocop:disableで無効化されているRuboCopの規約ごとに無効化が記述されているファイル数を集計するツール rdgrep を作成しました。(ちょっとややこしい) 背景 勤務先では下記のRuboCop configを使っているのですが、開発メンバーが入れ替わったりしてメンテされなくなり手元のソースコードにrubocop:disableが増えてきてしまってきたので今一度設定を整理する必要が出てきました。 https://github.com/Fablic/fablicop 重要ではないルールで警告が出続けると本当に守るべきルールまで軽視されてlintが無視されたり、とりあえずでrubocop:disableで無効化するようになってしまうので、不要なルールはこのconfig内でどんどん無効化してしまおうと考えています。 とはいえ効果的にルールの改善を行いたいため、差し当たってまずは設定されている規約と実際のコードの乖離がどの程度あるのかを知ろうと思い、以下のことを行ってConfigと実際のコードの差異を測ろうと考えました。 RuboCop出力を規約でグループ化して集計 rubocop:disableで無効化されている規約を集計 find . -type f -name "*.rb" -print0 | xargs -0 sed -i -e "s/rubocop:disable//g"等で無効化のコメントを消してからRubocop出力を規約でグループ化して集計すれば良いのではと思いましたが、古いプロダクトだと古いバージョンのRubyの書き方が残っていて規約違反として検出されるなどノイズが多く、人の手で恣意的に無効化している規約の一覧が欲しいのであえて分けました。 前者は既につくられている方がいましたが、後者ができるツールがなかったので自分で書くことにしました。 なぜRustで書くのか Rustは以前から流行っていて興味はあったものの、プログラマ歴が短いのでまずは今使っているRubyの造詣を深めるのに集中するのが先だと思い触れてきませんでした。しかし、 2022年はRubyGems 3.3.11でRust拡張の対応が実験的に入ったり、Rust版YJITがマージされたりだったりとRubyの周りにRustが進出してきた年だった 取り組む内容がそんなに難しい内容ではないので、数週間でどこまで新しい言語を勉強してコードを書けるかを試してみたかった ということでRubyistにも身近な存在になってきた&チャレンジしてみたいという理由でRustで書きました。 時間があまりなかったのでThe Rust Programming Language 日本語版 を途中までざっくりやって、その後は公式ドキュメントを参照しながらツール作成しました。 やったこと 集計にあたってrubocop:disableで無効化されている規約の数をそのまま測るのではなく、規約が無効化されているファイル数を計測することにしました。 理由としては範囲指定で無効化していたり、特定の行で無効化していたりと無効化の仕方が違うためです。 例えば以下のコードではStyle/NumericPredicate, Style/NumericLiterals共に無効化のコメントが書かれているのは1箇所ですが、実際にはこの規約に違反している箇所はStyle/NumericPredicateは1箇所、Style/NumericLiteralsは2箇所あります。 def a foo == 0 # rubocop:disable Style/NumericPredicate end # rubocop:disable Style/NumericLiterals def b 10000 end def c 100000 end # rubocop:enable Style/NumericLiterals ファイル数で確認する事ができればこの差異を避ける事ができると考えこの実装にしました。...

December 20, 2022 · craftscat

RubyKaigi2022 in 三重 オフライン参加レポート

RubyKaigi 2022に参加してきたので拙いながらもそのレポートです。 今回は初のオフライン参加で参加前は少し緊張していたのですが、3日間楽しみきることができました! 全部書いていくと長くなり書ききるのにも時間がかかってしまいそうなので開発体験に関わるいくつかテーマを絞って発表の感想などを書こうと思います。 WebAssemblyサポートについて 初回の発表はWebAssemblyについて。 RubyのWasm対応はこの以下の記事を見て気になっていたので楽しみにしていたセッションでした。 https://www.publickey1.jp/blog/22/rubywebassemblywasirubygems.html CookpadさんによるRubyPuzzlesもこれを使っているみたいです。 https://ruby-puzzles-2022.cookpad.tech/ 面白いなと思ったのはSwift, Rust, Goなど他の言語は実行するバイナリをWasmとしてビルドしてブラウザ上で実行するに対し、今回のセッションで紹介された仕組みではRubyのインタプリタ、ランタイムをWASMとして用意し実行するrbファイルと共にブラウザに渡し実行する点でした。これによりRubyアプリケーションのコードを再コンパイルすることなくそのまま動かせるのだとか。この仕組みは他のスクリプト言語でも応用できるそうです。 またシングルバイナリにする必要があったためインタプリタと実行するrbファイルをシングルファイルとしてデプロイするためにWebAssemblyバイナリに埋め込み可能なVFS仮想ファイルシステム)をつくったそうです。(しれっと言っていてビックリしました笑) またファイルシステムやOS依存に関しては、WASI(WebAssembly System Interface)で対応しているそうです。 今まではWebAssemblyが盛り上がっていてもその恩恵がいまいち理解できていなかったのですが、実際に見て、会場で触れてみてその影響のインパクトを実感できました。 CRuby を WebAssembly に移植する際に「例外処理」, 「Fiber」, 「保守的なGC」の3つの問題に直面し、これをAysncifyを使うことで解決したそうです。 同期的なCの処理を非同期なものにできるものらしいですが、私はここで初めて聞いたのでよくわからず。。 気になったので勉強してます。 型について Types teaches success, what will we do? https://rubykaigi.org/2022/presentations/fugakkbn.html#day1 gem_rbs_collection についての発表でした。 Ruby3.0ではRBSの導入されるもあまり普及していない原因の一つとして型が付いているgemが少ないことが挙げられるのではないかと言う話から始まりました。 gemの型定義を集めたgem_rbs_collection(TypeScriptで言うところの DefinitelyTyped)があるそうなのですが、RubyGems には17万を超えるgemが登録されている一方でgem_rbs_collectionには44個しか型定義がないとのことでした(0.025%)。思っていたより少ない。。 そこでgem_rbs_collectionへのcontributionが必要ということで、contributionのやり方について発表されていました。 手動生成や自動生成の使い分けなど具体的なやり方を実際に登壇者の方が書いたPRや作業の内容を元に解説されていました。 また規模が大きいgemだと全てのAPIを対応するのは難しいので、主要なAPIや自分のプロジェクトで使っている部分を追加すれば良いとのことでコントリビューションへのハードルが下がりました。 gem_rbs_collectionにコントリビューションしていく方法について実際の経験を踏まえて説明されていたので分かりやすく、コントリビューションにチャレンジしてみたくなりました。 参考) https://github.com/ruby/gem_rbs_collection/blob/main/docs/CONTRIBUTING.md RBS generation framework using Rack architecture https://rubykaigi.org/2022/presentations/_ksss_.html#day3 この発表では orthoses の紹介が行われました。 モチベーションとしてはHappy Hackingをゴールに型をありふれた状態にするために型ファイルを自動生成することを目指しているようです。 型情報の生成でRack architectureを参考にして生成される型の量と正確性、型情報生成における拡張性と柔軟性を解消したという内容でした。 CLIで用意せず、以下のようにRakeタスクなどのスクリプトで複数のMiddlewareを繋げることで破綻することなく複数機能を組み合せるやり方は柔軟性があって良さそうでした。 include, extendの追従やattr_accessorなどで動的定義されるメソッドに対応することもできるらしく、それならRailsでもある程度使えるのかなと考えていたら orthoses-rails というRails向けのものが紹介されていました。 Rack architectureを参考にしてどういう実装をしたかが主な内容だったので、どのような使い方ができそうかは実際に触ってみて試してみようと思います。 Let’s collect type info during Ruby running and automaticall https://rubykaigi....

September 11, 2022 · craftscat

First Post

Hello, world!

September 7, 2022 · craftscat