Project

General

Profile

Actions

Feature #227

closed

rb_scan_args() for keyword arguments

Added by nobu (Nobuyoshi Nakada) over 16 years ago. Updated over 13 years ago.

Status:
Closed
Target version:
[ruby-dev:35379]

Description

=begin
なかだです。

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はできる。
中田 伸悦
=end


Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #5454: keyword argumentsRejectedko1 (Koichi Sasada)10/18/2011Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0