Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Rubyに(ちょっと)コントリビュートできた話
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
YuheiNakasaka
November 13, 2024
390
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rubyに(ちょっと)コントリビュートできた話
YuheiNakasaka
November 13, 2024
More Decks by YuheiNakasaka
See All by YuheiNakasaka
四則演算の計算結果を返すプログラムを書きながら学習とは何かについて考える
yuheinakasaka
0
120
エンジニアリングマネージャーの仕事
yuheinakasaka
0
210
サラリーマンソフトウェアエンジニアのキャリア
yuheinakasaka
56
26k
LLMでコードレビューする際の自分用環境を整える
yuheinakasaka
0
390
AIプログラミング雑キャッチアップ
yuheinakasaka
25
9.8k
Featured
See All Featured
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
A Soul's Torment
seathinner
7
3.6k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
380
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
330
The agentic SEO stack - context over prompts
schlessera
0
920
GraphQLとの向き合い方2022年版
quramy
50
15k
Exploring anti-patterns in Rails
aemeredith
3
500
エンジニアに許された特別な時間の終わり
watany
108
250k
Everyday Curiosity
cassininazir
0
310
Raft: Consensus for Rubyists
vanstee
141
7.7k
Being A Developer After 40
akosma
91
590k
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