# ObjectC style keyword argument

**URL:** <https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014>\
**Category:** Development\
**Created:** [April 26, 2007, 4:23pm UTC](https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014 "2007-04-26T16:23:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [April 26, 2007, 4:23pm UTC](https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014/1 "2007-04-26T16:23:44Z")

</div>

e$B$J$+$@$G$9!#e(B

e$B$\*$H$H$$EE\<V$NCf$GBgBN$G$-$A$c$C$?$N$G$J$s$H$J$/e(B(e$BFfe(B)e$B!#e(B

class ObjC  
def copy:from: p [copy, from] end  
end  
ObjC.new.copy: “x”, from: “y” #=\> [“x”, “y”]

e$B$H$$$&46$8$G%a%=%C%IDj5A$b2DG=$K$J$j$^$7$?!#e(B

# Index: parse.y

— parse.y (revision 12223)  
+++ parse.y (working copy)  
@@ -529,4 +529,6 @@ static void ripper\_compile\_error(struct  
#endif

+ID rb\_alist\_id(VALUE);  
+  
%}

@@ -613,4 +615,5 @@ static void ripper\_compile\_error(struct  
%type f\_arglist f\_args f\_arg f\_arg\_item f\_optarg f\_marg  
f\_marg\_head f\_margs  
%type assoc\_list assocs assoc undef\_list backref string\_dvar  
for\_var  
+%type assoc\_call assoc\_arg  
%type block\_param opt\_block\_param block\_param\_def f\_opt  
%type bv\_decls opt\_bv\_decl bvar  
@@ -620,4 +623,5 @@ static void ripper\_compile\_error(struct  
%type fsym variable sym symbol operation operation2 operation3  
%type cname fname op f\_rest\_arg f\_block\_arg opt\_f\_block\_arg  
f\_norm\_arg  
+%type label\_args label\_arg  
/_%%%_/  
/_%  
@@ -1040,4 +1044,17 @@ stmt : keyword\_alias fitem {lex\_state =  
%_/  
}

- | primary\_value ‘.’ assoc\_call
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 ID associd = rb_alist_id($3->nd_lit);

```

- 

```
 $3->nd_next->nd_alen = $3->nd_alen - 1;

```

- 

```
 $$ = NEW_CALL($1, associd, $3->nd_next);

```

- 

```
 fixpos($$, $1);

```

- 

```
   /*%

```

- 

```
 $$ = dispatch3(call, $1, ripper_id2sym('.'),

```

- 

```
          ID2SYM(rb_alist_id(rb_ary_shift($3))));

```

- 

```
       $$ = method_arg($$, $3);

```

- 

```
   %*/

```

- 

```
   }

```

| primary\_value tCOLON2 tIDENTIFIER tOP\_ASGN command\_call  
{  
@@ -2830,4 +2847,82 @@ primary : literal  
%\*/  
}
- | keyword\_def label\_args
- 

```
   {

```

- 

```
 $<id>$ = cur_mid;

```

- 

```
 cur_mid = rb_alist_id($2);

```

- 

```
 in_def++;

```

- 

```
   /*%%%*/

```

- 

```
 local_push(0);

```

- 

```
   /*%

```

- 

```
   %*/

```

- 

```
   }

```

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 VALUE names = $2;

```

- 

```
 long i;

```

- 

```
 for (i = 0; i < RARRAY_LEN(names); ++i) {

```

- 

```
     ID id = SYM2ID(RARRAY_PTR(names)[i]);

```

- 

```
     shadowing_lvar(id);

```

- 

```
     arg_var(id);

```

- 

```
 }

```

- 

```
 $<node>$ = new_args(NEW_ARGS_AUX(0, i), 0, 0, 0, 0);

```

- 

```
   /*%

```

- 

```
 $$ = dispatch5(params, $2, Qnil, Qnil, Qnil, Qnil);

```

- 

```
   %*/

```

- 

```
   }

```

- 

```
 bodystmt

```

- 

```
 keyword_end

```

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 NODE *body = remove_begin($5);

```

- 

```
 reduce_nodes(&body);

```

- 

```
 $$ = NEW_DEFN(cur_mid, $<node>4, body, NOEX_PRIVATE);

```

- 

```
       fixpos($$, $<node>4);

```

- 

```
       local_pop();

```

- 

```
 in_def--;

```

- 

```
 cur_mid = $<id>3;

```

- 

```
   /*%

```

- 

```
 $$ = dispatch3(def, cur_mid, $<val>4, $5);

```

- 

```
 in_def--;

```

- 

```
 cur_mid = $<id>3;

```

- 

```
   %*/

```

- 

```
   }

```

- | keyword\_def singleton dot\_or\_colon {lex\_state = EXPR\_FNAME;}  
label\_args
- 

```
   {

```

- 

```
 in_single++;

```

- 

```
   /*%%%*/

```

- 

```
 local_push(0);

```

- 

```
   /*%

```

- 

```
   %*/

```

- 

```
   }

```

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 VALUE names = $5;

```

- 

```
 long i;

```

- 

```
 for (i = 0; i < RARRAY_LEN(names); ++i) {

```

- 

```
     ID id = SYM2ID(RARRAY_PTR(names)[i]);

```

- 

```
     shadowing_lvar(id);

```

- 

```
     arg_var(id);

```

- 

```
 }

```

- 

```
 $<node>$ = new_args(NEW_ARGS_AUX(0, i), 0, 0, 0, 0);

```

- 

```
   /*%

```

- 

```
 $$ = dispatch5(params, $5, Qnil, Qnil, Qnil, Qnil);

```

- 

```
   %*/

```

- 

```
   }

```

- 

```
 bodystmt

```

- 

```
 keyword_end

```

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 NODE *body = remove_begin($8);

```

- 

```
 reduce_nodes(&body);

```

- 

```
 $$ = NEW_DEFS($2, rb_alist_id($5), $<node>7, body);

```

- 

```
       fixpos($$, $2);

```

- 

```
       local_pop();

```

- 

```
 in_single--;

```

- 

```
   /*%

```

- 

```
 $$ = dispatch5(defs, $2, $3, ID2SYM(rb_alist_id($5)), $<val>7, 

```

$8);

- 

```
 in_single--;

```

- 

```
   %*/

```

- 

```
   }

```

| keyword\_break  
{  
@@ -4329,4 +4424,48 @@ assoc : arg\_value tASSOC arg\_value  
;

+assoc\_call : assoc\_arg

- | assoc\_call ‘,’ assoc\_arg
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 rb_ary_concat($1->nd_lit, $3->nd_lit);

```

- 

```
 $$ = list_concat($1, $3->nd_next);

```

- 

```
   /*%

```

- 

```
 rb_ary_push(rb_ary_entry($1, 0), rb_ary_entry($3, 0));

```

- 

```
 rb_ary_push($1, rb_ary_entry($3, 1));

```

- 

```
   %*/

```

- 

```
   }

```

- 

+assoc\_arg : tLABEL arg\_value

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 $$ = list_append(NEW_LIST(rb_ary_new3(1, ID2SYM($1))), $2);

```

- 

```
   /*%

```

- 

```
     $$ = rb_assoc_new(rb_ary_new3(1, $1), $2);

```

- 

```
   %*/

```

- 

```
   }

```

- ;
- 

+label\_args : label\_arg

- 

```
   {

```

- 

```
 $$ = rb_ary_new3(1, $1);

```

- 

```
   }

```

- | label\_args label\_arg
- 

```
   {

```

- 

```
 rb_ary_push($1, $2);

```

- 

```
 $$ = $1;

```

- 

```
   }

```

- ;  
+label\_arg : tLABEL
- 

```
   {

```

- 

```
               /*%%%*/

```

- 

```
 if (!is_local_id($1))

```

- 

```
     yyerror("formal argument must be local variable");

```

- 

```
 $$ = ID2SYM($1);

```

- 

```
               /*%

```

- 

```
       $$ = dispatch1(label_arg, ID2SYM($1));

```

- 

```
               %*/

```

- 

```
   }

```

- ;
- 

operation : tIDENTIFIER  
| tCONSTANT  
@@ -6795,4 +6934,6 @@ parser\_yylex(struct parser\_params \*parse  
if ((lex\_state == EXPR\_BEG && !cmd\_state) ||  
lex\_state == EXPR\_ARG ||

- lex\_state == EXPR\_DOT ||
- lex\_state == EXPR\_FNAME ||  
lex\_state == EXPR\_CMDARG) {  
if (peek(’:’) && !(lex\_p + 1 \< lex\_pend && lex\_p[1] == ‘:’)) {  
@@ -8501,4 +8642,11 @@ rb\_id2name(ID id)  
}

+ID  
+rb\_alist\_id(VALUE names)  
+{

- VALUE name = rb\_str\_cat(rb\_ary\_join(names, rb\_str\_new2(":")), “:”,  
1);
- return rb\_intern2(RSTRING\_PTR(name), RSTRING\_LEN(name));  
+}
- 

static int  
symbols\_i(VALUE sym, ID value, VALUE ary)

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [April 26, 2007, 6:13pm UTC](https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014/2 "2007-04-26T18:13:05Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:30735] ObjectC style keyword argument”  
on Thu, 26 Apr 2007 23:22:56 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|e$B$\*$H$H$$EE\<V$NCf$GBgBN$G$-$A$c$C$?$N$G$J$s$H$J$/e(B(e$BFfe(B)e$B!#e(B

e$B$“!”@h$r1[$5$l$?!#;d$O$:$C$He(Breduce/reduce conflicte$B$KG:$^$5$le(B  
e$B$F$^$7$?!#$$$d!"$b$C$He(BObjective-Ce$B$K;w$;$h$&$H;W$C$?$N$,GT0xe(B  
e$B$J$s$G$9$,e(B([x copy: y from:  
z]e$B$H=q$1$k$h$&$K$7$?$+$C$?e(B)e$B!#e(B

| class ObjC  
| def copy:from: p [copy, from] end  
| end  
| ObjC.new.copy: “x”, from: “y” #=\> [“x”, “y”]  
|  
|e$B$H$$$&46$8$G%a%=%C%IDj5A$b2DG=$K$J$j$^$7$?!#e(B

e$B%a%=%C%IDj5A$Oe(B

def copy:from:(x,y) p [x, y] end

e$B$+!“$”$k$$$Oe(B

def copy: x from: y; p [x, y] end

e$B$NJ}$,NI$/$J$$$G$9$+$M!)e(B (e$BA0\<T$G==J,$@$1$Ie(B)e$B!#e(B  
e$B%-!\<%o!\<%I$N=EJ#$b$"$j$($^$9$7!#!Ve(Bdo:value:value:e$B!W$H$+!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [April 28, 2007, 5:27pm UTC](https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014/3 "2007-04-28T17:27:29Z")

</div>

e$B$J$+$@$G$9!#e(B

At Fri, 27 Apr 2007 01:12:18 +0900,  
Yukihiro M. wrote in [ruby-dev:30737]:

> |e$B$\*$H$H$$EE\<V$NCf$GBgBN$G$-$A$c$C$?$N$G$J$s$H$J$/e(B(e$BFfe(B)e$B!#e(B
> 
> e$B$"!"@h$r1[$5$l$?!#;d$O$:$C$He(Breduce/reduce conflicte$B$KG:$^$5$le(B  
> e$B$F$^$7$?!#$$$d!"$b$C$He(BObjective-Ce$B$K;w$;$h$&$H;W$C$?$N$,GT0xe(B  
> e$B$J$s$G$9$,e(B([x copy: y from: z]e$B$H=q$1$k$h$&$K$7$?$+$C$?e(B)e$B!#e(B

e$B\<0$N@hF,$Ke(B[e$B$,Mh$k$3$H$N$J$$e(BCe$B$J$i$H$b$+$/!“G[Ns$,$”$k$N$Ge(Brubye$B$8$ce(B  
e$BL5M}$C$]$$5$$,$7$^$9!#$"$H0z?t4V$N%+%s%^$N\>JN,$b!"$+$J$j$-$D$$e(B  
e$B@)8B$,$D$/$3$H$K$J$j$=$&$G$9!#e(B

> e$B%a%=%C%IDj5A$Oe(B
> 
> def copy:from:(x,y) p [x, y] end
> 
> e$B$+!"$"$k$$$Oe(B
> 
> def copy: x from: y; p [x, y] end
> 
> e$B$NJ}$,NI$/$J$$$G$9$+$M!)e(B (e$BA0\<T$G==J,$@$1$Ie(B)e$B!#e(B  
> e$B%-!\<%o!\<%I$N=EJ#$b$"$j$($^$9$7!#!Ve(Bdo:value:value:e$B!W$H$+!#e(B

e$B=EJ#$rK:$l$F$^$7$?!#$H$j$"$($:DL\>o%a%=%C%I$@$1$G$9$,!"8e\<T$G!#e(B

# Index: parse.y

— parse.y (revision 12223)  
+++ parse.y (working copy)  
@@ -520,4 +520,13 @@ static void ripper\_compile\_error(struct  
#endif

+#ifdef RIPPER  
+#define MUST\_ASSOC(cons, car, cdr) do { \

- if ((cons) == (car) || (cons) == (cdr) || \
- 

```
 TYPE(cons) != T_ARRAY || RARRAY_LEN(cons) != 2) { \

```

- 

```
 (cons) = rb_assoc_new((car), (cdr)); \

```

- } \
- } while (0)  
+#endif
- 

/\* Older versions of Yacc set YYMAXDEPTH to a very low value by default  
(150,  
for instance). This is too low for Ruby to parse some files, such  
as  
@@ -529,4 +538,9 @@ static void ripper\_compile\_error(struct  
#endif

+ID rb\_alist\_id(VALUE);  
+#ifndef RIPPER  
+static void assoc\_arg\_vars(struct parser\_params \*, NODE \*);  
+#endif  
+  
%}

@@ -613,4 +627,5 @@ static void ripper\_compile\_error(struct  
%type f\_arglist f\_args f\_arg f\_arg\_item f\_optarg f\_marg  
f\_marg\_head f\_margs  
%type assoc\_list assocs assoc undef\_list backref string\_dvar  
for\_var  
+%type assoc\_call assoc\_arg assoc\_fargs assoc\_farg  
%type block\_param opt\_block\_param block\_param\_def f\_opt  
%type bv\_decls opt\_bv\_decl bvar  
@@ -1040,4 +1055,17 @@ stmt : keyword\_alias fitem {lex\_state =  
%\*/  
}

- | primary\_value ‘.’ assoc\_call
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 ID associd = rb_alist_id($3->nd_lit);

```

- 

```
 $3->nd_next->nd_alen = $3->nd_alen - 1;

```

- 

```
 $$ = NEW_CALL($1, associd, $3->nd_next);

```

- 

```
 fixpos($$, $1);

```

- 

```
   /*%

```

- 

```
 $$ = dispatch3(call, $1, ripper_id2sym('.'),

```

- 

```
          ID2SYM(rb_alist_id(rb_ary_shift($3))));

```

- 

```
       $$ = method_arg($$, $3);

```

- 

```
   %*/

```

- 

```
   }

```

| primary\_value tCOLON2 tIDENTIFIER tOP\_ASGN command\_call  
{  
@@ -2830,4 +2858,35 @@ primary : literal  
%\*/  
}
- | keyword\_def assoc\_fargs
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 $<id>$ = cur_mid;

```

- 

```
 cur_mid = rb_alist_id($2->nd_tval);

```

- 

```
 in_def++;

```

- 

```
 local_push(0);

```

- 

```
 assoc_arg_vars(parser, $2->nd_var);

```

- 

```
 $2->nd_var = 0;

```

- 

```
   /*%

```

- 

```
   %*/

```

- 

```
   }

```

- 

```
 bodystmt

```

- 

```
 keyword_end

```

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 NODE *body = remove_begin($4);

```

- 

```
 reduce_nodes(&body);

```

- 

```
 $$ = NEW_DEFN(cur_mid, NEW_ARGS(RARRAY_LEN($2->nd_tval), 0),

```

- 

```
         body, NOEX_PRIVATE);

```

- 

```
       fixpos($$, $2);

```

- 

```
       local_pop();

```

- 

```
 in_def--;

```

- 

```
 cur_mid = $<id>3;

```

- 

```
   /*%

```

- 

```
 $$ = dispatch3(def, rb_alist_id(RARRAY_PTR($2)[0]),

```

- 

```
          RARRAY_PTR($2)[1], $5);

```

- 

```
 in_def--;

```

- 

```
 cur_mid = $<id>3;

```

- 

```
   %*/

```

- 

```
   }

```

| keyword\_break  
{  
@@ -4315,5 +4374,5 @@ assoc : arg\_value tASSOC arg\_value  
/\*%  
$$ = dispatch2(assoc\_new, $1, $3);

- 

```
 if ($$ == $1) $$ = rb_assoc_new($1, $3);

```

- 

```
 MUST_ASSOC($$, $1, $3);
   %*/
   }

```

@@ -4324,5 +4383,69 @@ assoc : arg\_value tASSOC arg\_value  
/\*%  
$$ = dispatch2(assoc\_new, $1, $2);

- 

```
 if ($$ == $1) $$ = rb_assoc_new($1, $2);

```

- 

```
 MUST_ASSOC($$, $1, $2);

```

- 

```
   %*/

```

- 

```
   }

```

- ;
- 

+assoc\_call : assoc\_arg

- | assoc\_call ‘,’ assoc\_arg
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 rb_ary_concat($1->nd_lit, $3->nd_lit);

```

- 

```
 $$ = list_concat($1, $3->nd_next);

```

- 

```
   /*%

```

- 

```
 rb_ary_push(rb_ary_entry($1, 0), rb_ary_entry($3, 0));

```

- 

```
 rb_ary_push($1, rb_ary_entry($3, 1));

```

- 

```
   %*/

```

- 

```
   }

```

- 

+assoc\_arg : tLABEL arg\_value

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 $$ = list_append(NEW_LIST(rb_ary_new3(1, ID2SYM($1))), $2);

```

- 

```
   /*%

```

- 

```
     $$ = rb_assoc_new(rb_ary_new3(1, $1), $2);

```

- 

```
   %*/

```

- 

```
   }

```

- ;
- 

+assoc\_fargs : assoc\_farg

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 ID pid = $1->nd_pid, mid = $1->nd_mid;

```

- 

```
 rb_gc_force_recycle((VALUE)$1);

```

- 

```
 $$ = NEW_ARGS(rb_ary_new3(1, ID2SYM(pid)),

```

- 

```
         NEW_LIST((NODE *)mid));

```

- 

```
 /* nd_tval, nd_var */

```

- 

```
   /*%

```

- 

```
 $$ = $1;

```

- 

```
 RARRAY_PTR($$)[0] = rb_ary_new3(1, RARRAY_PTR($1)[0]);

```

- 

```
 RARRAY_PTR($$)[1] = rb_ary_new3(1, RARRAY_PTR($1)[1]);

```

- 

```
   %*/

```

- 

```
   }

```

- | assoc\_fargs assoc\_farg
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 ID pid = $2->nd_pid, mid = $2->nd_mid;

```

- 

```
 rb_gc_force_recycle((VALUE)$2);

```

- 

```
 $$ = $1;

```

- 

```
 rb_ary_push($$->nd_tval, ID2SYM(pid));

```

- 

```
 $$->nd_var = list_append($$->nd_var, (NODE *)mid);

```

- 

```
   /*%

```

- 

```
 $$ = $1;

```

- 

```
 rb_ary_push(RARRAY_PTR($$)[0], RARRAY_PTR($2)[0]);

```

- 

```
 rb_ary_push(RARRAY_PTR($$)[1], RARRAY_PTR($2)[1]);

```

- 

```
   %*/

```

- 

```
   }

```

- ;  
+assoc\_farg : tLABEL f\_norm\_arg
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 if (!is_local_id($2))

```

- 

```
     yyerror("formal argument must be local variable");

```

- 

```
 $$ = NEW_ARGS_AUX($1, $2);

```

- 

```
   /*%

```

- 

```
       $$ = dispatch2(assoc_farg, $1, $2);

```

- 

```
 MUST_ASSOC($$, $1, $2);
   %*/
   }

```

@@ -6795,4 +6918,6 @@ parser\_yylex(struct parser\_params \*parse  
if ((lex\_state == EXPR\_BEG && !cmd\_state) ||  
lex\_state == EXPR\_ARG ||

- lex\_state == EXPR\_DOT ||
- lex\_state == EXPR\_FNAME ||  
lex\_state == EXPR\_CMDARG) {  
if (peek(’:’) && !(lex\_p + 1 \< lex\_pend && lex\_p[1] == ‘:’)) {  
@@ -8501,4 +8626,28 @@ rb\_id2name(ID id)  
}

+ID  
+rb\_alist\_id(VALUE names)  
+{

- VALUE name = rb\_str\_cat(rb\_ary\_join(names, rb\_str\_new2(":")), “:”,  
1);
- return rb\_intern2(RSTRING\_PTR(name), RSTRING\_LEN(name));  
+}
- 

+#ifndef RIPPER  
+static void  
+assoc\_arg\_vars(struct parser\_params \*parser, NODE \*var)  
+{

- NODE \*next;
- 
- while (var) {
- ID id = var-\>nd\_pid;
- shadowing\_lvar(id);
- arg\_var(id);
- next = var-\>nd\_next;
- rb\_gc\_force\_recycle((VALUE)var);
- var = next;
- }  
+}  
+#endif
- 

static int  
symbols\_i(VALUE sym, ID value, VALUE ary)

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 2, 2007, 3:29am UTC](https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014/4 "2007-05-02T03:29:20Z")

</div>

e$B$J$+$@$G$9!#e(B

At Fri, 27 Apr 2007 01:12:18 +0900,  
Yukihiro M. wrote in [ruby-dev:30737]:

> e$B%a%=%C%IDj5A$Oe(B

> e$B$+!"$"$k$$$Oe(B
> 
> def copy: x from: y; p [x, y] end

e$B$3$l$C$F$d$O$j%+%s%^$J$7$G$9$+e(B?

# Index: parse.y

— parse.y (revision 12239)  
+++ parse.y (working copy)  
@@ -538,4 +538,9 @@ static void ripper\_compile\_error(struct  
#endif

+ID rb\_alist\_id(VALUE);  
+#ifndef RIPPER  
+static void assoc\_arg\_vars(struct parser\_params \*, NODE \*);  
+#endif  
+  
%}

@@ -622,4 +627,5 @@ static void ripper\_compile\_error(struct  
%type f\_arglist f\_args f\_arg f\_arg\_item f\_optarg f\_marg  
f\_marg\_head f\_margs  
%type assoc\_list assocs assoc undef\_list backref string\_dvar  
for\_var  
+%type assoc\_call assoc\_arg assoc\_fargs assoc\_farg  
%type block\_param opt\_block\_param block\_param\_def f\_opt  
%type bv\_decls opt\_bv\_decl bvar  
@@ -1049,4 +1055,17 @@ stmt : keyword\_alias fitem {lex\_state =  
%\*/  
}

- | primary\_value ‘.’ assoc\_call
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 ID associd = rb_alist_id($3->nd_lit);

```

- 

```
 $3->nd_next->nd_alen = $3->nd_alen - 1;

```

- 

```
 $$ = NEW_CALL($1, associd, $3->nd_next);

```

- 

```
 fixpos($$, $1);

```

- 

```
   /*%

```

- 

```
 $$ = dispatch3(call, $1, ripper_id2sym('.'),

```

- 

```
          ID2SYM(rb_alist_id(rb_ary_shift($3))));

```

- 

```
 $$ = method_arg($$, $3);

```

- 

```
   %*/

```

- 

```
   }

```

| primary\_value tCOLON2 tIDENTIFIER tOP\_ASGN command\_call  
{  
@@ -2839,4 +2858,65 @@ primary : literal  
%\*/  
}
- | keyword\_def assoc\_fargs
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 $<id>$ = cur_mid;

```

- 

```
 cur_mid = rb_alist_id($2->nd_tval);

```

- 

```
 in_def++;

```

- 

```
 local_push(0);

```

- 

```
 assoc_arg_vars(parser, $2->nd_var);

```

- 

```
 $2->nd_var = 0;

```

- 

```
   /*%

```

- 

```
   %*/

```

- 

```
 lex_state = EXPR_BEG;

```

- 

```
   }

```

- 

```
 bodystmt

```

- 

```
 keyword_end

```

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 NODE *body = remove_begin($4);

```

- 

```
 reduce_nodes(&body);

```

- 

```
 $$ = NEW_DEFN(cur_mid, NEW_ARGS(RARRAY_LEN($2->nd_tval), 0),

```

- 

```
         body, NOEX_PRIVATE);

```

- 

```
 fixpos($$, $2);

```

- 

```
 local_pop();

```

- 

```
 in_def--;

```

- 

```
 cur_mid = $<id>3;

```

- 

```
   /*%

```

- 

```
 $$ = dispatch3(def, rb_alist_id(RARRAY_PTR($2)[0]),

```

- 

```
          RARRAY_PTR($2)[1], $5);

```

- 

```
 in_def--;

```

- 

```
 cur_mid = $<id>3;

```

- 

```
   %*/

```

- 

```
   }

```

- | keyword\_def singleton dot\_or\_colon {lex\_state = EXPR\_FNAME;}
- 

```
 assoc_fargs

```

- 

```
   {

```

- 

```
 in_single++;

```

- 

```
   /*%%%*/

```

- 

```
 local_push(0);

```

- 

```
 assoc_arg_vars(parser, $5->nd_var);

```

- 

```
 $5->nd_var = 0;

```

- 

```
   /*%

```

- 

```
   %*/

```

- 

```
 lex_state = EXPR_BEG;

```

- 

```
   }

```

- 

```
 bodystmt

```

- 

```
 keyword_end

```

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 NODE *body = remove_begin($7);

```

- 

```
 reduce_nodes(&body);

```

- 

```
 $$ = NEW_DEFS($2, rb_alist_id($5->nd_tval),

```

- 

```
         NEW_ARGS(RARRAY_LEN($5->nd_tval), 0), body);

```

- 

```
 fixpos($$, $2);

```

- 

```
 local_pop();

```

- 

```
   /*%

```

- 

```
 $$ = dispatch5(defs, $2, $3,

```

- 

```
          ID2SYM(rb_alist_id(RARRAY_PTR($5)[0])),

```

- 

```
          RARRAY_PTR($5)[1], $7);

```

- 

```
   %*/

```

- 

```
 in_single--;

```

- 

```
   }

```

| keyword\_break  
{  
@@ -4338,4 +4418,69 @@ assoc : arg\_value tASSOC arg\_value  
;

+assoc\_call : assoc\_arg

- | assoc\_call ‘,’ assoc\_arg
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 rb_ary_concat($1->nd_lit, $3->nd_lit);

```

- 

```
 $$ = list_concat($1, $3->nd_next);

```

- 

```
   /*%

```

- 

```
 rb_ary_push(rb_ary_entry($1, 0), rb_ary_entry($3, 0));

```

- 

```
 rb_ary_push($1, rb_ary_entry($3, 1));

```

- 

```
   %*/

```

- 

```
   }

```

- 

+assoc\_arg : tLABEL arg\_value

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 $$ = list_append(NEW_LIST(rb_ary_new3(1, ID2SYM($1))), $2);

```

- 

```
   /*%

```

- 

```
 $$ = rb_assoc_new(rb_ary_new3(1, $1), $2);

```

- 

```
   %*/

```

- 

```
   }

```

- ;
- 

+assoc\_fargs : assoc\_farg

- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 ID pid = $1->nd_pid, mid = $1->nd_mid;

```

- 

```
 rb_gc_force_recycle((VALUE)$1);

```

- 

```
 $$ = NEW_ARGS(rb_ary_new3(1, ID2SYM(pid)),

```

- 

```
         NEW_LIST((NODE *)mid));

```

- 

```
 /* nd_tval, nd_var */

```

- 

```
   /*%

```

- 

```
 $$ = $1;

```

- 

```
 RARRAY_PTR($$)[0] = rb_ary_new3(1, RARRAY_PTR($1)[0]);

```

- 

```
 RARRAY_PTR($$)[1] = rb_ary_new3(1, RARRAY_PTR($1)[1]);

```

- 

```
   %*/

```

- 

```
   }

```

- | assoc\_fargs opt\_comma assoc\_farg
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 ID pid = $3->nd_pid, mid = $3->nd_mid;

```

- 

```
 rb_gc_force_recycle((VALUE)$3);

```

- 

```
 $$ = $1;

```

- 

```
 rb_ary_push($$->nd_tval, ID2SYM(pid));

```

- 

```
 $$->nd_var = list_append($$->nd_var, (NODE *)mid);

```

- 

```
   /*%

```

- 

```
 $$ = $1;

```

- 

```
 rb_ary_push(RARRAY_PTR($$)[0], RARRAY_PTR($3)[0]);

```

- 

```
 rb_ary_push(RARRAY_PTR($$)[1], RARRAY_PTR($3)[1]);

```

- 

```
   %*/

```

- 

```
   }

```

- ;  
+assoc\_farg : tLABEL f\_norm\_arg
- 

```
   {

```

- 

```
   /*%%%*/

```

- 

```
 if (!is_local_id($2))

```

- 

```
     yyerror("formal argument must be local variable");

```

- 

```
 $$ = NEW_ARGS_AUX($1, $2);

```

- 

```
   /*%

```

- 

```
 $$ = dispatch2(assoc_farg, $1, $2);

```

- 

```
 NEED_ASSOC($$, $1, $2);

```

- 

```
   %*/

```

- 

```
 lex_state = EXPR_FNAME;

```

- 

```
   }

```

- ;
- 

operation : tIDENTIFIER  
| tCONSTANT  
@@ -4374,4 +4519,9 @@ opt\_nl : /\* none \*/  
;

+opt\_comma : /\* none \*/

- | ‘,’
- 

```
 {lex_state = EXPR_FNAME;}

```

- ;
- 

rparen : opt\_nl ‘)’  
;  
@@ -6804,4 +6954,6 @@ parser\_yylex(struct parser\_params \*parse  
if ((lex\_state == EXPR\_BEG && !cmd\_state) ||  
lex\_state == EXPR\_ARG ||

- lex\_state == EXPR\_DOT ||
- lex\_state == EXPR\_FNAME ||  
lex\_state == EXPR\_CMDARG) {  
if (peek(’:’) && !(lex\_p + 1 \< lex\_pend && lex\_p[1] == ‘:’)) {  
@@ -8510,4 +8662,27 @@ rb\_id2name(ID id)  
}

+ID  
+rb\_alist\_id(VALUE names)  
+{

- VALUE name = rb\_str\_cat(rb\_ary\_join(names, rb\_str\_new2(":")), “:”,  
1);
- return rb\_intern2(RSTRING\_PTR(name), RSTRING\_LEN(name));  
+}
- 

+#ifndef RIPPER  
+static void  
+assoc\_arg\_vars(struct parser\_params \*parser, NODE \*var)  
+{

- while (var) {
- NODE \*next = var-\>nd\_next;
- ID id = var-\>nd\_pid;
- 
- rb\_gc\_force\_recycle((VALUE)var);
- shadowing\_lvar(id);
- arg\_var(id);
- var = next;
- }  
+}  
+#endif
- 

static int  
symbols\_i(VALUE sym, ID value, VALUE ary)

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 2, 2007, 11:15am UTC](https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014/5 "2007-05-02T11:15:55Z")

</div>

e$BKYG7Fb$G$9!#e(B

> |\> def copy: x from: y; p [x, y] end  
> |  
> |e$B$3$l$C$F$d$O$j%+%s%^$J$7$G$9$+e(B?
> 
> e$B8F$S=P$7$,%+%s%^$"$j$J$i%+%s%^$"$j$G$7$g$&!#$D$^$jB7$($k$Y$-e(B  
> e$B$@$H;W$$$^$9!#$G$b!"$[$s$H$ON\>J}%+%s%^$,$J$$$N$,$$$$$J$"!#e(B  
> yacce$B$K$OE$i$l$A$c$&$1$I!"$J$s$H$+$@$^$;$J$$$+$H2h:vCf!#e(B

def copy: x from: y e$B$H!"%3%s%^$,$J$$$H!“e(Bx e$B$He(B from  
e$B$,$R$H$+$?$^$je(B  
e$B$K8+$($J$$$G$7$g$&$+!#$”$H!“DL\>o$N0z?t$O%3%s%^$G6h@Z$k$N$G!”%3%se(B  
e$B%^$J$7$H;H$$J,$1$J$1$l$P$J$i$J$$$H:.Mp$7$=$&$J5$$,e(B…

e$B$H$3$m$G!"$3$l$O%a%=%C%IL\>$b%-!\<%o!\<%I$N$h$&$K$J$k$N$G$9$M!#$3$Ne(B  
e$B7A\<0$H!“0z?t$KBP$7$F$N$_%i%Y%k$r$D$1$k%-!\<%o!\<%I0z?t$H$N4X78$O$Ie(B  
e$B$N$h$&$K$J$k$N$G$7$g$&$+!#;d$N$$$&%-!\<%o!\<%I0z?t$H$O!"8=:_$O$h$/e(B  
Hash e$B$GBeMQ$5$l$F$$$k$b$N$N$3$H$G$9!#$D$^$j!”=gHV$G$J$/L\>A0$G;Xe(B  
e$BDj$9$k0z?t!#e(BRuby 2.0  
e$B$G$OF3F~M=Dj$H;W$$9~$s$G$k$N$G$9$,!"$I$N$he(B  
e$B$&$K=q$1$k$h$&$K$J$k$N$G$7$g$&$+!#e(B

e$B!te(B ruby-dev  
e$B%"!\<%+%$%V$r$A$g$C$HD4$Y$?$H$3$m$G$O!“e(B2004e$BG/$Ke(B  
e$B5DO@$,$”$C$?$"$H$O:#$^$G$J$$$h$&$K8+$($^$9$,!"8+Mn$H$7$F$^$7e(B  
e$B$?$i$9$_$^$;$s!#$"$k$$$Oe(B 1.9 e$B$G4{$K\<B8=:Q$_!)e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [May 2, 2007, 7:02am UTC](https://www.ruby-forum.com/t/objectc-style-keyword-argument/93014/6 "2007-05-02T07:02:33Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:30744] Re: ObjectC style keyword argument”  
on Wed, 2 May 2007 10:28:32 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|\> e$B$+!“$”$k$$$Oe(B  
|\>  
|\> def copy: x from: y; p [x, y] end  
|  
|e$B$3$l$C$F$d$O$j%+%s%^$J$7$G$9$+e(B?

e$B8F$S=P$7$,%+%s%^$“$j$J$i%+%s%^$”$j$G$7$g$&!#$D$^$jB7$($k$Y$-e(B  
e$B$@$H;W$$$^$9!#$G$b!“$[$s$H$ON\>J}%+%s%^$,$J$$$N$,$$$$$J$”!#e(B  
yacce$B$K$OE$i$l$A$c$&$1$I!"$J$s$H$+$@$^$;$J$$$+$H2h:vCf!#e(B
