Ruby 3のキーワード引数について考える8. 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
14. 議題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
15. 議題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
16. 議題2
• Ruby 2のように動くメソッドを簡単に定義したい
– 案1:諦めてもらう
• 手動マージしてください
– 案2:互換定義用のAPIを提供する
def result_with_hash(***h); end
ruby2 def result_with_hash(h); end
define_ruby2_method(:result_with_hash){}
16
17. 議題3
• Ruby 2.6 と Ruby 3 の両方でうごく委譲は?
– 委譲専用の記法を導入する? #3447
def forward(...)
target(...)
end
17
18. 議題3'
• Ruby 2.6 と Ruby 3 の両方でうごく委譲は?
– ↓は Ruby2.6で若干問題がある
– forward() が target(**{}) を呼ぶ
• target()とtarget(**{})は微妙に意味が違う
• 実用上は問題ない?
def forward(*args, **kw, &blk)
target(*args, **kw, &blk)
end
18
19. 議題3''
• Ruby 2.5 は **{} がバグっている #15052
• 2.6で、どう直す?
def foo(opt=42)
p opt
end
foo(**{}) #=> 42
h={}
foo(**h) #=> {}
19
20. 議題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