キーワード引数 (Keyword Arguments)
仮引数の形
def f(hoge: "HOGE", foo: "FOO")
def f(hoge:, foo:)
実引数の形
f(hoge: "AAA", foo:"BBB")
Rubyist Magazine - Ruby 2.0.0 のキーワード引数
Ruby 2 Keyword Arguments
def f(hoge: "HOGE", foo: "FOO") #仮引数
puts hoge
puts foo
end
f(hoge: "AAA", foo:"BBB") #実引数
def f(hoge:, foo:) #仮引数
puts hoge
puts foo
end
f(hoge: "AAA", foo:"BBB") #実引数
実引数のところがちょっぴりObjective-Cぽい。
Objective-Cと違って順番を変えれるけどね。
実引数でHashを渡しているのに、仮引数では、Hashではなくなり個別の変数に入っている(与えたHashが個別の変数に分解されている)。
いわゆる名前付き引数と思うんだけど違うのかなあ。
Positional Arguments (日本語名は?)
一番普通のやつ。
def f(hoge, foo) #仮引数
puts hoge
puts foo
end
f("AAA", "BBB") #実引数
Keyword arguments vs Positional arguments
Keyword argumentsのがコールしてるとこ読みやすいよねえ。
引数の順番も入れ替えれる。
まあVBA
のときから名前付き引数がスタンダートって感じよねえ。
#可変長引数 (英語名は? Splat?)
可変長引数 - うなの日記
仮引数の形
def f(*hoge)
実引数の形
f("AAA", "BBB")
実引数で与えたものを*
で宣言した変数にArray にして入る。
def f(*hoge) #仮引数
p hoge #=> ["AAA", "BBB"]
end
f("AAA", "BBB") #実引数
def f(*hoge) #仮引数
p hoge #=> [{:hoge=>"AAA", :foo=>"BBB"}]
end
f(hoge: "AAA", foo:"BBB") #実引数
Double Splat(日本語ではなんていうんだろう?)
ruby - What does a double * (splat) operator do - Stack Overflow
Drat! - Ruby has a Double Splat - Firmafon Developers Blog
Ruby and the double splat operator | Simplificator
仮引数の形
def f(**options)
実引数の形
f hoge: "AAA", foo: "BBB"
**
で宣言した変数にHashで入る。
def f(**options) #仮引数
p options #=> {:hoge=>"AAA", :foo=>"BBB"}
end
f hoge: "AAA", foo: "BBB" #実引数
んー
def f(options = {})
との違いがわからんぞ。 Double Splatの方が、実引数に変なのきたときにエラーにしてくれるって感じかな。
はじめは options = {}
のシンタックスシュガーが**options
と思ったんだが...
なぜrailsのActiveRecordの引数で受け取れる形が多様なのか!?
Module: ActiveRecord::FinderMethods — Documentation for rails (4.0.0)
Person.find(1) # returns the object for ID = 1
Person.find("1") # returns the object for ID = 1
Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
Person.find([1]) # returns an array for the object with ID = 1
上記呼び出し例を見てもらえばわかるが、実引数に受け取れる形が多様すぎる。
どうして
Person.find(1, 2, 6)
Person.find([7, 17])
Person.find(1) # これは可変長引数(*のやつ)で受け取ってるので配列になるのは自明
こんな風に、配列でうけとったり、そうでなかったりできるのか!?
普通に自分で書くと、
def f(*args)
p args #=> [[1, 2]]
end
f [1,2]
配列の入れ子になってしまう...
RoRのソースを読み進めると...
def find_with_ids(*ids)
raise UnknownPrimaryKey.new(@klass) if primary_key.nil?
expects_array = ids.first.kind_of?(Array)
return ids.first if expects_array && ids.first.empty?
ids = ids.flatten.compact.uniq
case ids.size
発見!!
ids = ids.flatten.compact.uniq
秘密はここと見た!
def f(*args)
p args.flatten.compact.uniq #=> [1,2]
end
f [1,2]
ほらね!
実引数でHash渡してるのに仮引数*args
実引数でHash渡してるのに仮引数*args
になってるメソッドがちょいちょいある気がする。簡単にすると以下のように*args
でArrayになったやつをHashに戻してた
def f(*args)
p args #=> [{:hoge=>"AAA", :foo=>"BBB"}]
other_f(*args)
end
def other_f(args)
p args #=> {:hoge=>"AAA", :foo=>"BBB"}
end
f hoge: "AAA", foo: "BBB"
Ruby - 可変長引数を引き回す - Qiita
Ruby覚え書き - Qiita
可変長引数を使い回すやつの応用と思われる。
- 配列の展開
- 実引数の頭に「*」をつけると配列を複数の引数として渡す事ができる
- 配列をメソッド呼び出しの引数リストとして渡したいときに便利
参考までに
def f(*args)
p args #=> [{:hoge=>"AAA", :foo=>"BBB"}]
other_f(*args)
end
def other_f(*args)
p args #=> [{:hoge=>"AAA", :foo=>"BBB"}]
end
f hoge: "AAA", foo: "BBB"