From: Akinori MUSHA Date: 2010-09-13T12:48:37+09:00 Subject: [ruby-dev:42244] Re: Introducing "rb_scan_keyword_args()" (was Re: Re: Enhancing Numeric#step) --pgp-sign-Multipart_Mon_Sep_13_12:48:37_2010-1 Content-Type: text/plain; charset=ISO-2022-JP At Sun, 12 Sep 2010 19:51:21 +0900, I wrote: > At Thu, 9 Sep 2010 09:59:45 +0900, > matz wrote: > > でキーワード辞書を取れたり、 > > > > rb_scan_keywords(kw, "by", &step, "to", &limit, NULL); > > > > で、キーワード辞書を分解したりするようなAPIはどうだろうかと > > 考えています。 > >  少し考えてから、 rb_scan_keyword_args() というものを設計・実装 > してみました。仕様は以下の差分中に(日本語も)あるので見てみて > ください。 > >  改良点として、 fmt の頭に ':' を置くと、キーワード名として > const char * でなく ID を取るという機能を付けると、何度も呼び > 出されることを考慮して効率のために rb_intern() の結果を取って > おくようなところでも使えるのかなと思っています。  rb_intern() 程度の手間は強いてもいいかなと思ったので、IDを取る ようにしました。(パッチは省きます) >  まあ、そこはAPI仕様としては枝葉として、幹としての機能はこれで > いかがでしょうか。  想定されるRubyのAPIと対比してみると、こういう感じです。 # 省略可能キーワード argc = rb_scan_keyword_args(argc, argv, "2:", &x, &y, &opt); rb_scan_keyword_args(opt, "*", rb_intern("color"), &color, 0, &rest); def point(x, y, color: color = :DEFAULT, **rest) end # 必須キーワード argc = rb_scan_keyword_args(argc, argv, "2:", &x, &y, &opt); rb_scan_keyword_args(opt, "1*", rb_intern("color"), &color, 0, &rest); def point(x, y, color: color, **rest) end # 残りを読み捨て argc = rb_scan_keyword_args(argc, argv, "2:", &x, &y, &opt); rb_scan_keyword_args(opt, "1*", rb_intern("color"), &color, 0, NULL); def point(x, y, color: color, **rest) end # 知らないキーワードはwarning argc = rb_scan_keyword_args(argc, argv, "2:", &x, &y, &opt); rb_scan_keyword_args(opt, "1", rb_intern("color"), &color, 0); def point(x, y, color: color, **rest) warn "unknown keywords: #{rest.keys.inspect}" if rest && $VERBOSE end # 知らないキーワードはArgumentError argc = rb_scan_keyword_args(argc, argv, "2:", &x, &y, &opt); rb_scan_keyword_args(opt, "1!", rb_intern("color"), &color, 0); def point(x, y, color: color) end -- Akinori MUSHA / http://akinori.org/ --pgp-sign-Multipart_Mon_Sep_13_12:48:37_2010-1 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEABECAAYFAkyNnxUACgkQkgvvx5/Z4e5GzgCg06aBGieQVbn2kgVjGYpZqyfO ec4An3obHjl1ERETCJQ0Nmub7/DEKXKq =HQck -----END PGP SIGNATURE----- --pgp-sign-Multipart_Mon_Sep_13_12:48:37_2010-1--