はじめに
この記事は俺GW頑張ったというGWアドベントカレンダーの5月1日の記事です。
プログラミング言語Rubyにテストの修正やbuiltin対応などでパッチを投げてきた時の知見などを振りかえってみたかったので書いてみた。
やったこと
テスト修正関連
そもそもRubyのパッチとかを書き始めたのは、ruby-jp
でコミッターの方が「テストの修正をしたいんですが、手伝っていただける人いませんか?」と投げられてたのがきっかけ。
具体的に修正したテストはこれら
remove warning & support multi-run test for test/psych/visitors/test_… #2881
remove warning & support multi-run test for test/psych_test_yaml.rb #2887
Fix remove warning & support multi-run test for test/psych/visitors/test_to_ruby.rb #2893
support multi-run test for test/did_you_mean/test_verbose_formatter.rb #2894
support multi-run test for test/webrick/test_filehandler.rb #2896
support multi-run test for test_readline.rb #2914
support multi-run test for test/did_you_mean/spell_checking/test_class_name_check.rb #2880
Rubyではmake test-all
というすべてのテストを行うコマンドがあり、それをmake test-all TESTS=--repeat-count=2
のように繰り返して実行するといくつかのテストが落ちてしまうという問題が起きていました。
原因としては、変数などの初期化がされていないので二回目以降に落ちるということが多かったですね。 とはいえ、原因の判別は結構難しかった……。
テストの修正を行うにあたってまずは落ちているテストのリストアップを行いました。 この時、注意したのは自分の環境要因で落ちているものもあった点ですね
たとえばWSL(Ubuntu 18.04)を使用した環境ではネットワーク関係やIO周りのテストで落ちることがありましたが、VM(Ubuntu 18.04)上では落ちることがありませんでした。 このように環境によってテストの結果が変わるので、そこを分離していくことから始めました。
結果的にWSL上でのテスト環境はネットワークやIO周りの問題が解決しなかったので、おとなしくVMを使って作業することに。
そこから落ちているテストをピックアップしていき、落ちている原因らしきものをチェックしていきました。
チェックにあたっては、最小の構成でテストが落ちるコードを書いて動きを確認。その後に、原因らしき箇所を洗うという流れで進めました おおよその場合は同じテストファイルの中で初期化が済んでいないということが原因であり、それらは比較的対処が楽でしたね。
辛かったのは、別のテストで値が変更されておりテストが落ちるケースでした……。 こういうテストが落ちる箇所は再現コードを作るのが難しく、なんどもRubyリファレンスマニュアルを読みふけり、Rubyの実装を読んでました。
こんな感じでテスト関係は修正を進め、無事テストが通るようになりました。
builtin対応
builtinというRubyとCを使ってRubyのメソッドを実装できる仕組みがあります。
builtinを使うことでキーワード引数を使ったメソッドはHash
を作らないため高速に動作するようになります。
詳しくはこちらを参考に
Ruby(とC)でRubyを実装してみた(builtinで遊んでみた)
そのbuiltin対応をパッチとして投げました。
support builtin for Kernel#clone #2954
support builtin for Kernel#Float #3048
Kernel#clone
とKernel#Float
の実装をbuiltin対応させて処理を高速化できたのは結構うれしかったですね。
ただ、ベンチマークを追加し忘れていたりしたので、その点は反省点かも。
ちなみに、今もいくつかのメソッドのbuiltin対応を進めていますね(いくつかベンチマーク忘れてたりしたけど)。
support builtin for Numeric#clone #2968
support builtin for Dir class singleton method #3007
support builtin for String#lines & String#each_line #3022
support builtin for Exception#full_message #3038
support builtin for Kernel#Integer #3054
その他
ドキュメント周りやCIの修正、不要になった関数宣言の削除とかやったりしましたね。
Add array.rb to .document #2904
Fix AppVeyor CI sometimes fail #2979
Fix AppVeyor pull request CI #2983
remove unused rb_str_clear define #3059
この辺は、あんまり複雑なことはしていないですね。 ソースコード読んだりしてて気になったので修正投げた感じです。
CIは落ちてたので修正投げたんですが、挙動が良くわからないところもあり良い感じの修正にならなかったのが残念ですね。
今現在も、二つほどCのコードを変更したものを投げたりしてますね。
Add rb_ary_max_or_min func #3060
Move rb_big_isqrt defination to internal/bignum.h #3065
おわりに
振り返ってみると意外とアレコレ修正パッチ書いてるなぁという感じ。
今後も何かしら修正できそうなもの見つけたらパッチを投げていきたいと改めて思ったね。