Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Rubyに(ちょっと)コントリビュートできた話
Search
YuheiNakasaka
November 13, 2024
1
280
Rubyに(ちょっと)コントリビュートできた話
YuheiNakasaka
November 13, 2024
Tweet
Share
More Decks by YuheiNakasaka
See All by YuheiNakasaka
LLMでコードレビューする際の自分用環境を整える
yuheinakasaka
0
200
AIプログラミング雑キャッチアップ
yuheinakasaka
25
9k
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
Speed Design
sergeychernyshev
33
1.4k
For a Future-Friendly Web
brad_frost
180
10k
KATA
mclloyd
PRO
32
15k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
Docker and Python
trallard
47
3.7k
Optimizing for Happiness
mojombo
379
70k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Code Review Best Practice
trishagee
74
19k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.6k
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