e$B$J$+$@$G$9!#e(B
rb_scan_args()e$B$G%-!<%o!<%I0z?t$KBP1~$9$k%Q%C%A$rH/7!$7$^$7$?!#e(B
rb_scan_args(argc, argv, “11:foo”, &mandatory, &optional, &foo)
e$B$H$+e(B
rb_scan_args(argc, argv, “11::”, &mandatory, &optional,
rb_intern(“foo”), &foo, (ID)0)
e$B$H$+=q$1$k$h$&$K$J$k$O$:$@$C$?$H;W$$$^$9!#e(B
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*);