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

Ruby 3のキーワード引数について考える

Yusuke Endoh
September 15, 2018

Ruby 3のキーワード引数について考える

大江戸Ruby会議07 - だしもの

https://regional.rubykaigi.org/oedo07/

Yusuke Endoh

September 15, 2018
Tweet

More Decks by Yusuke Endoh

Other Decks in Research

Transcript

  1. 問題:キーワード拡張が安全でない • rest引数をとるメソッドのキーワード拡張は危険 – 既存コードが動かなくなるリスクがある – optional引数も同様にダメ • バグ報告が多数来ている –

    #8316,#11967,#12104,#12717,#12821,#13336,#13647,#14130 • 実際にAPI拡張で困っている – Thread.new(stack_size: 100000)とか – Struct.new(keyword_init: true)とか 6
  2. 問題の原因 • キーワードとハッシュを自動変換していること def foo(h) p h #=>{:k=>42} end foo(k:

    42) def foo(k: 1) p k #=> 42 end foo({ k: 42 }) キーワード➔ハッシュ ハッシュ➔キーワード 7
  3. Ruby 3での解決提案 • キーワードハッシュの変換をやめる #14183 – キーワードかハッシュか、明示してください 注意:Ruby 3の決定事項ではない def

    foo(h) p h #=>{:k=>42} end foo(k: 42) def foo(k: 1) p k #=> 42 end foo({ k: 42 }) def foo(h) p h[:k] #=> 42 end foo({ k: 42 }) def foo(h) p h #=>{:k=>42} end foo({ k: 42 }) def foo(**h) p h #=>{:k=>42} end foo(k: 42) def foo(k: 1) p k #=> 42 end foo(**{ k: 42 }) 8
  4. 議題1' • Ruby 3で、以下はキーワード?ハッシュ? – 案1:キーの種類で自動分割する? • foo({"str"=>1}, key:2) –

    案2:非Symbolがあったら全部ハッシュ? • foo({"str"=>1, key:2}) – 案3:文法エラーにする?(混ぜるな危険) • 参考:こういうAPIは実在する(Kernel#spawn) foo("str"=>1, key:2) 14
  5. 議題1'' • Ruby 3で、以下はキーワード?ハッシュ? – 案1:キーの種類で自動分割する? • foo({"s"=>2,"ss"=>4}, k:1, kk:3)

    – 案2:非Symbolがあったら全部ハッシュ? • foo({k:1, "s"=>2, kk:3, "ss"=>4}) – 案3:文法エラーにする?(混ぜるな危険) foo(k:1, "s"=>2, kk:3, "ss"=>4) 15
  6. 議題3' • Ruby 2.6 と Ruby 3 の両方でうごく委譲は? – ↓は

    Ruby2.6で若干問題がある – forward() が target(**{}) を呼ぶ • target()とtarget(**{})は微妙に意味が違う • 実用上は問題ない? def forward(*args, **kw, &blk) target(*args, **kw, &blk) end 18
  7. 議題3'' • Ruby 2.5 は **{} がバグっている #15052 • 2.6で、どう直す?

    def foo(opt=42) p opt end foo(**{}) #=> 42 h={} foo(**h) #=> {} 19
  8. 議題3''' • Ruby 2.6で、以下の意味は? foo(**{}) def foo(opt=42,**kw) p [opt, kw]

    end foo({}, **{}) #foo({})と同じ #=> [42, {}] def foo(opt=42) p opt end foo(**{}) #=> {} 案1:「無」とみなす? 案2:空ハッシュを渡す? 案3:いい感じに(難しい) 20