Feature #227
rb_scan_args() for keyword arguments
| Status: | Closed | Start date: | ||
|---|---|---|---|---|
| Priority: | Low | Due date: | ||
| Assignee: | % Done: | 0% |
||
| Category: | - | |||
| Target version: | 2.0.0 |
Description
なかだです。
rb_scan_args()でキーワード引数に対応するパッチを発掘しました。
rb_scan_args(argc, argv, "11:foo", &mandatory, &optional, &foo)
とか
rb_scan_args(argc, argv, "11::", &mandatory, &optional, rb_intern("foo"), &foo, (ID)0)
とか書けるようになるはずだったと思います。
Index: class.c
===================================================================
--- class.c (revision 17903)
+++ class.c (working copy)
@@ -871,4 +871,5 @@ rb_scan_args(int argc, const VALUE *argv
const char *p = fmt;
VALUE *var;
+ VALUE opt = 0;
va_list vargs;
@@ -876,4 +877,13 @@ rb_scan_args(int argc, const VALUE *argv
if (*p == '*') goto rest_arg;
+ if (strchr(fmt, ':')) {
+ if (argc > 0 && TYPE(opt = argv[argc-1]) == T_HASH) {
+ --argc;
+ }
+ else {
+ opt = 0;
+ }
+ if (*p == ':') goto keyword;
+ }
if (ISDIGIT(*p)) {
@@ -895,9 +905,6 @@ rb_scan_args(int argc, const VALUE *argv
for (; i<n; i++) {
var = va_arg(vargs, VALUE*);
- if (argc > i) {
- if (var) *var = argv[i];
- }
- else {
- if (var) *var = Qnil;
+ if (var) {
+ *var = argc > i ? argv[i] : Qnil;
}
}
@@ -905,5 +912,32 @@ rb_scan_args(int argc, const VALUE *argv
}
- if(*p == '*') {
+ keyword:
+ if (*p == ':') {
+ if (p[1] == ':') {
+ ID name;
+ while ((name = va_arg(vargs, ID)) != 0) {
+ var = va_arg(vargs, VALUE*);
+ if (var) {
+ *var = opt ? rb_hash_lookup(opt, name) : Qnil;
+ }
+ }
+ }
+ else {
+ do {
+ const char *beg = ++p;
+ if (*p != '_' && !ISALPHA(*p)) goto error;
+ while (*p == '_' || ISALNUM(*p)) p++;
+ if (*p && !strchr(":*&", *p)) goto error;
+ var = va_arg(vargs, VALUE*);
+ if (var) {
+ *var = opt ?
+ rb_hash_lookup(opt, rb_intern2(beg, p - beg)) :
+ Qnil;
+ }
+ } while (*p == ':');
+ }
+ }
+
+ if (*p == '*') {
rest_arg:
var = va_arg(vargs, VALUE*);
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦
Related issues
History
Updated by ko1 (Koichi Sasada) almost 4 years ago
- Assignee set to matz (Yukihiro Matsumoto)
Updated by znz (Kazuhiro NISHIYAMA) about 2 years ago
- Target version set to 2.0.0
Updated by shyouhei (Shyouhei Urabe) over 1 year ago
- Status changed from Open to Assigned
Updated by knu (Akinori MUSHA) 11 months ago
キーワードに対応した値を取り出す部分はまだ入っていないです。
私の案とまつもとさんの案があって、どうしようかというところで止まっています。
本当に今Rubyに割ける時間がないのでポインタなしのコメントだけですみませんが、一応。