Ruby でふつーの引数でもキーワード引数でも渡せるようにしたい
def func(a, a:)
— はいと (@HaiTo_Linux) 2018年6月8日
puts a
end
ってしたときに、
func 'a'
ってしたら第一引数の a が利用できて
func a: 'a'
ってしたら第二引数の a が a として利用できる
みたいな、こう、Keyword引数としても使えるしそうでなくても使えるみたいなやつがほしいです
Swift の named parameters みたいな使い方のやつですかね。
こんなんでどうでしょうか、というのを tw では雑に書いたもののちゃんと清書していなかったので置いときます。
class Foo FOO__ARG1 = Object.new private_constant :FOO__ARG1 FOO__NAME = Object.new private_constant :FOO__NAME def foo(_arg1 = FOO__ARG1, name: FOO__NAME) unless FOO__ARG1.equal?(_arg1) name = _arg1 end if FOO__NAME.equal?(name) raise ArgumentError end puts "name: #{name}" end end Foo.new.foo(name: 'taro') Foo.new.foo('hanako') Foo.new.foo
$ ruby foo.rb name: taro name: hanako Traceback (most recent call last): 1: from foo.rb:24:in `<main>' foo.rb:15:in `foo': ArgumentError (ArgumentError)
nil を使うと nil を渡せないということがあるので適当に Object.new して object_id 比較をしています。
引数が足りない場合は自前で raise してます。
これ書くのめんどいなーと思って、self.class.instance_method(__method__).params
あたりでなんとかできないかなーとは思いつつ、実のところ自分ではそんなに使いそうにないからここでやめときます、
すごい雑にやるなら
— Ⓜ️ (@hanachin_) June 10, 2018
def func(_a = nil, a: _a)
p a
end
func(1)
func(a: 1)
みたいな感じでも...と思ってしまいましたがArgumentError投げたい場合はだるそうですね
class Foo FOO__ARG1 = Object.new private_constant :FOO__ARG1 def foo(_arg1 = FOO__ARG1, name: _arg1) if FOO__ARG1.equal?(name) raise ArgumentError end puts "name: #{name}" end end
仮引数使うというアイデアのおかげでちょっと短くなりました。