Created
December 8, 2013 06:55
-
-
Save k-tsj/7854083 to your computer and use it in GitHub Desktop.
Extend rb_scan_args to get keyword arguments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/array.c b/array.c | |
index 9a93d7f..b673c63 100644 | |
--- a/array.c | |
+++ b/array.c | |
@@ -4429,7 +4429,7 @@ static VALUE sym_random; | |
static VALUE | |
rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary) | |
{ | |
- VALUE opts, randgen = rb_cRandom; | |
+ VALUE rnd, randgen = rb_cRandom; | |
long i, len; | |
static ID keyword_ids[1]; | |
@@ -4437,14 +4437,10 @@ rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary) | |
keyword_ids[0] = rb_intern("random"); | |
} | |
- if (OPTHASH_GIVEN_P(opts)) { | |
- VALUE rnd; | |
- rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd); | |
- if (rnd != Qundef) { | |
- randgen = rnd; | |
- } | |
+ rb_scan_args(argc, argv, "00:01", NULL, keyword_ids, &rnd); | |
+ if (rnd != Qundef) { | |
+ randgen = rnd; | |
} | |
- rb_check_arity(argc, 0, 0); | |
rb_ary_modify(ary); | |
i = len = RARRAY_LEN(ary); | |
RARRAY_PTR_USE(ary, ptr, { | |
diff --git a/class.c b/class.c | |
index 66495eb..c13f4b3 100644 | |
--- a/class.c | |
+++ b/class.c | |
@@ -1727,8 +1727,9 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) | |
const char *p = fmt; | |
VALUE *var; | |
va_list vargs; | |
- int f_var = 0, f_hash = 0, f_block = 0; | |
+ int f_var = 0, f_hash = 0, f_get_kwargs = 0, f_block = 0; | |
int n_lead = 0, n_opt = 0, n_trail = 0, n_mand; | |
+ int n_keyword_required = 0, n_keyword_optional = 0; | |
int argi = 0; | |
VALUE hash = Qnil; | |
@@ -1757,6 +1758,18 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) | |
if (*p == ':') { | |
f_hash = 1; | |
p++; | |
+ if (ISDIGIT(*p)) { | |
+ f_get_kwargs = 1; | |
+ n_keyword_required = *p - '0'; | |
+ p++; | |
+ if (ISDIGIT(*p)) { | |
+ n_keyword_optional = *p - '0'; | |
+ p++; | |
+ } | |
+ else { | |
+ rb_fatal("bad scan arg format: %s", fmt); | |
+ } | |
+ } | |
} | |
if (*p == '&') { | |
f_block = 1; | |
@@ -1831,6 +1844,11 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) | |
/* capture an option hash - phase 2: assignment */ | |
if (f_hash) { | |
var = va_arg(vargs, VALUE *); | |
+ if (f_get_kwargs) { | |
+ ID *ids = va_arg(vargs, ID *); | |
+ VALUE *values = va_arg(vargs, VALUE *); | |
+ rb_get_kwargs(NIL_P(hash) ? 0 : hash, ids, n_keyword_required, n_keyword_optional, values); | |
+ } | |
if (var) *var = hash; | |
} | |
/* capture iterator block */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment