Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Rubyに(ちょっと)コントリビュートできた話
Search
YuheiNakasaka
November 13, 2024
1
200
Rubyに(ちょっと)コントリビュートできた話
YuheiNakasaka
November 13, 2024
Tweet
Share
More Decks by YuheiNakasaka
See All by YuheiNakasaka
AIプログラミング雑キャッチアップ
yuheinakasaka
1
45
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.3k
Why Our Code Smells
bkeepers
PRO
336
57k
We Have a Design System, Now What?
morganepeng
51
7.4k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
175
52k
For a Future-Friendly Web
brad_frost
176
9.5k
What's in a price? How to price your products and services
michaelherold
244
12k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
Testing 201, or: Great Expectations
jmmastey
42
7.2k
Code Review Best Practice
trishagee
67
18k
Measuring & Analyzing Core Web Vitals
bluesmoon
6
250
Transcript
Rubyに(ちょっと)コントリビュートできた話 Roppongi.rb #24 2024/11/14 X: @razokulover 1
自己紹介 中坂雄平(Yuhei Nakasaka) X: @razokulover 株式会社GA Technologies 不動産投資に関する各種サービスを提供 主にRailsでフロントエンドからバックエンドまで幅広くやっています 入社1ヶ月くらいなのでまだまだ何もわからん状態
最近はCursorに甘やかされながら何とか生きております... 2
今日話すこと Rubyに初めてコントリビュートできたのでその経緯と内容の話 どんなPRか 問題の解説 どう修正したか 学び 3
どんなPRか 4
Fix behavior of trying to parse non-string objects #499 -
ruby/json 5
先月マージされました(2024/10) 2年の時を経てマージ。PRしてたことすら完全に忘れていた。 標準ライブラリとはいえRuby本体へのコントリビュートは初めて 6
要約 respond_to?(:to_str) で true を返すオブジェクトに to_str を呼ぶとStringが返っ てくると想定されているのに nil を返してしまう変なオブジェクトがあり、それを
JSON に渡すと TypeError: no implicit conversion of nil into String が発生す る挙動を修正 7
8
問題の解説 9
ActiveSupportにActiveSupport::InheritableOptionsというOpenStructのような便利なクラ スがあります。 h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
h.girl # => 'Mary' h.boy # => 'John' 身近なところだと credentials.yml に対して Rails.credentials.foo.bar のように アクセスできるようにしてくれています。 https://github.com/rails/rails/blob/main/railties/lib/rails/application/configuration.rb#L77 10
こいつは見た目はHashっぽくて is_a?(Hash) で true を返します(これは良い)。 しかしなぜか respond_to?(:to_str) で true を返します(ちなみに標準のHashは
false )。 h = ActiveSupport::InheritableOptions.new({ a: 1, b: 2 }) h.is_a? Hash #=> true h.respond_to?(:to_str) #=> true では to_str を呼んでみましょう。 11
h = ActiveSupport::InheritableOptions.new({ a: 1, b: 2 }) h.to_str #=>
nil nilが返ります(なんで) 12
以前の JSON(object, args) の実装は引数で受け取るオブジェクトとして普通のHash を想定していました。 def JSON(object, *args) # ↓`to_str`を持ってるObjectは文字列を返すのは当たり前やろ
if object.respond_to? :to_str JSON.parse(object.to_str, args.first) else JSON.generate(object, args.first) end end だがしかし、 、お分かりのように ActiveSupport::InheritableOptions の to_str は nil を返します。 13
よって↓こんなことをすると TypeError: no implicit conversion of nil into String が発生します。
h = ActiveSupport::InheritableOptions.new({ a: 1, b: 2 }) JSON(h) #=> TypeError: no implicit conversion of nil into String 14
要約(再掲) respond_to?(:to_str) で true を返すオブジェクトに to_str を呼ぶとStringが返っ てくると想定されているのに nil を返してしまう変なオブジェクトがあり、それを
JSON に渡すと TypeError: no implicit conversion of nil into String が発生す る挙動を修正 解説終了 15
どう修正したか 16
A. to_str を信用しないようにした ruby/jsonに下記の変更を含むPRを送りました(2022)。 def JSON(object, *args) if object.is_a?(String) return
JSON.parse(object, args.first) elsif object.respond_to?(:to_str) # ここ↓。どんなObjectの`to_str`も信用しない。 str = object.to_str if str.is_a?(String) return JSON.parse(object.to_str, args.first) end end JSON.generate(object, args.first) end 17
学び 重箱の隅を突いたようなユースケースでも必要な修正と判断されれば取り込まれる 今回は ActiveSupport::InheritableOptions という比較的Railsのコアで使わ れているクラスだったから対応されたのかも Rubyの処理系へのコントリビュートはCプログラマとしての深い経験がないと難 しそうだけど標準ライブラリならRubyで書かれているものも多いのでそこまで難 しくない ライブラリによっては
CONTRIBUTING.md が用意されている場合もあるが、無 い場合も多い。過去のPRの雰囲気を読みながら手探りでやっていきましょ う。 18
終わり 19