Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rubyに(ちょっと)コントリビュートできた話

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for YuheiNakasaka YuheiNakasaka
November 13, 2024
340

 Rubyに(ちょっと)コントリビュートできた話

Avatar for YuheiNakasaka

YuheiNakasaka

November 13, 2024
Tweet

Transcript

  1. 8

  2. 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
  3. こいつは見た目は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
  4. 以前の 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
  5. よって↓こんなことをすると 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
  6. 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