Feature #227

rb_scan_args() for keyword arguments

Added by Nobuyoshi Nakada over 6 years ago. Updated over 3 years ago.

[ruby-dev:35379]
Status:Closed
Priority:Low
Assignee:Yukihiro Matsumoto

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

Related to Ruby trunk - Feature #5454: keyword arguments Rejected 10/18/2011

Associated revisions

Revision 38700
Added by Eric Hodel about 2 years ago

  • doc/syntax/methods.rdoc: Added return values and scope sections, slightly modified from the original patch. Fixes #227 from github by Dave Brown.

Revision 38700
Added by Eric Hodel about 2 years ago

  • doc/syntax/methods.rdoc: Added return values and scope sections, slightly modified from the original patch. Fixes #227 from github by Dave Brown.

History

#1 Updated by Koichi Sasada over 6 years ago

  • Assignee set to Yukihiro Matsumoto

=begin

=end

#2 Updated by Kazuhiro NISHIYAMA almost 5 years ago

  • Target version set to 2.0.0

=begin

=end

#3 Updated by Shyouhei Urabe over 4 years ago

  • Status changed from Open to Assigned

=begin

=end

#4 Updated by Koichi Sasada over 3 years ago

  • Status changed from Assigned to Closed

違う形で入ったらしいので終了.

#5 Updated by Akinori MUSHA over 3 years ago

キーワードに対応した値を取り出す部分はまだ入っていないです。
私の案とまつもとさんの案があって、どうしようかというところで止まっています。

本当に今Rubyに割ける時間がないのでポインタなしのコメントだけですみませんが、一応。

Also available in: Atom PDF