«前の日記(2010-06-17) 最新 次の日記(2010-06-24)» 編集

Matzにっき


2010-06-18 [長年日記]

_ [Ruby] Ruby2.0の新機能(かもしれないもの)(4) keyword arguments

注意。このエントリはRuby 2.0に入るかもしれない機能について述べていますが、本機能が本当に2.0に採用されるかどうかは、未定です。

「まだあるのか」とか思われそうだけど、まだあるんです。

今度は長年採用すると言いつつ、ほったらかしの最右翼、キーワード引数である。 調べたら、キーワード引数については、2003年のRubyConfではすでに話題にしている。 どんだけ前から口にしてたんだ。「やるやる詐欺」だな(苦笑)。

その時の仕様はこんな感じ。

def foo(a, b: 42, **keys)
   p [a,b,keys]
end
foo(1)             # => [1,42,{}]
foo(2, b: 5)       # => [2,5,{}]
foo(3, b: 4, c: 6) # => [3,4,{:c=>6}]

まあ、そんなに悪くない。基本的にはこの線を踏襲しようと思う。 文法としては、ブロック引数の直前に

keyword: value,..., **keys

というキーワード引数を置くことができる、というもの。 Pythonと違ってキーワード引数は明示的に指定しなければならない。 通常の引数名が勝手にキーワードになったりはしない。

問題はrest引数と組み合わさった時。

def baz(*rest, a:4, b:0, **keys)
  ...
end

として、以下の呼び出しを行ったらどうなるか。

baz()           # rest=[],a=4,b=0,keys={}
baz(1)          # rest=[1],a=4,b=0,keys={}
baz(a:1)        # rest=[],a=1,b=0,keys={}
baz(a:1,b:2)    # rest=[],a=1,b=2,keys={}
baz(1,2,b:2)    # rest=[1,2],a=4,b=2,keys={}
baz(c:2)        # rest=[],a=4,b=0,keys={c:2}

つまり、以下のルールに従う。

  • 引数が0の場合、キーワード指定は{}とみなす。
  • 引数が1個以上の時、末尾の引数がHashでなければ、キーワード指定は{}とみなす。
  • 引数が1個以上で、末尾がHashであればそれがキーワード指定。引数リストから取り除く※
    • キーワード指定に、キーワード引数があればそれを取り除き、キーワードと同じ名前の変数に代入
    • キーワード指定にキーワードが含まれていなければ、デフォルト値を代入
    • 「**keys」が指定されていない時に、キーワード指定がキーワード引数として定義されていないキーを含む時には、ArgumentError例外

なお、※の部分はRubyConf 2005のキーノートで紹介したものと動作が違う。

この仕様ではキーワード指定はあくまでも通常引数の一部なので、 通常引数の引渡の時には *rest で受けて、 foo(*rest) と呼び出せばよい(はず)。

呼び出し側のキーワード引数は結局は引数リスト末尾のハッシュに過ぎないので、 呼び出し側では foo(**keys) のような文法は(本来は)不要。 ただし、対称性と型チェックのために採用する可能性は、なきにしもあらず(あんまり積極的ではない)。

本日のツッコミ(全6件) [ツッコミを入れる]
_ whiteleaf (2010-06-18 19:00)

これが実装された場合、現在の def f(a);p a;end; f(b:10)#=>{:b=>10} のような書き方は使えなくなるのでしょうか

_ まつもと (2010-06-18 19:48)

ご心配なく。defの引数でキーワード引数定義がなければ、現状となにも変わりません。

_ KL1 (2010-06-29 14:37)

RubyもPythonのように、猫でも分かるようなキーワード引数形式を採用する訳には行かないのでしょうか?

_ まつもと (2010-06-29 17:45)

Pythonのキーワード引数が「猫でも分かる」という意見には同意しません。あれ、実際には、位置引数と名前引数が混じるとかなり複雑ですよ。

_ KL1 (2010-06-29 23:33)

そういう事でしたか。 <br>ご教示をいただきまして、大変ありがとうございました。

_ Bogdan Gusiev (2010-07-01 03:04)

"def foo" <br> <br>^ yes, I guess that.

お名前:
E-mail:
コメント:
[]

«前の日記(2010-06-17) 最新 次の日記(2010-06-24)» 編集

track feed Matzにっき Creative Commons License This work is licensed under a Creative Commons License.