65480


Ruby では、ハッシュを使ってオプショナル引数を実現できます。

[code]

    def f(a, b, opts = {})
        puts({a: a, b: b, opts: opts})
    end
    
[/code]

この関数 `f`
にあらかじめ決まった引数を渡すラッパー関数を考えます。このラッパー関数では適当な条件によってオプショナル引数を渡すかどうか分岐することとします。たとえば次のように書けます。

[code]

    def f_wrapper(flag)
        opts = {}
        if flag
            opts[:additional_arg] = 1234
        end
        f(42, "Hello", opts)
    end
    
[/code]

これと同じようなことを、ハッシュではなくデフォルト値を持つキーワード引数によってオプショナル引数を実装している場合にも実現したいです。

[code]

    def g(a:, b:, additional_arg: nil)
        puts({a: a, b: b, additional_arg: additional_arg})
    end
    
[/code]

デフォルト値が何であるかあらかじめ分かっていれば、たとえば次のように書けそうだなというところまでは考えました。

[code]

    def g_wrapper(flag)
        g(
            a: 42,
            b: "Hello",
            additional_arg: flag ? 1234 : nil,
        )
    end
    
[/code]

しかしデフォルト値が分かっていない（あるいは、簡単に変わりうる）というシチュエーションで `g_wrapper`
と同じ処理をスッキリ書くことはできるでしょうか？

次のように書くことはできますが、可能であれば同じ部分を複数回書かずに済ませたいです（実際は `a` とか `b`
とかの部分がより複雑になっていると思ってください）。

[code]

    def g_wrapper(flag)
        if flag
            g(a: 42, b: "Hello", additional_arg: 1234)
        else
            g(a: 42, b: "Hello")
        end
    end
    
[/code]

Ruby はあまりたくさん使っておらず `f_wrapper`
の実装も標準的なものでは無いかもしれません。もし何かしら設計の時点からおかしいようであればそのように回答していただければありがたいです。

環境：Ruby 2.6 （ただし 2.7 でも構いません）


CC BY-SA 4.0
2020-04-09T02:32:20.753
65479
2020-04-09T02:58:28.483
19110
question
ruby
オプショナルなキーワード引数を使った関数へ場合分けしつつ委譲するパターンの書き方


単に重複を避けるという意味であれば、以下のようなコードで動作すると思います（2.7で動作確認済みです）。

[code]

    def g_wrapper(flag)
      args = {a: 42, b: 'hello'}
      args.merge!({additional_arg: 1234}) if flag
      g(**args)
    end
    
[/code]


CC BY-SA 4.0
2020-04-09T02:58:28.483
65480
2020-04-09T02:58:28.483
442
65479
answer