From: Robert Klemme Date: 2013-01-24T18:30:21+09:00 Subject: Re: order of parameters and arguments On Thu, Jan 24, 2013 at 3:12 AM, Patricia J. wrote: > Can someone pls explain why in the following example that *c is left > empty? After the required arguments have been filled, doesn't it make > more sense that since b=1 has already been assigned a value to give the > remaining value/argument (2) to *c? > > Can you pls confirm that arguments with default values are always paired > before sponge arguments (*c)? > > . . . . > > def args_unleashed(a, b=1, *c, d, e) > puts "Arguments: " > p a, b, c, d, e > end > > args_unleashed(1, 2, 3, 4) > > => [1, 2, [], 3, 4] There is pattern matching going on. (This was introduced in Ruby 1.9.* btw.) The arguments passed are matched against the argument list definition and distribute to formal arguments to create a match. There are even more involved patterns possible: $ ruby args.rb ERROR FUN1: args=[1] error=# ERROR FUN2: args=[1] error=# ERROR FUN1: args=[1, 2] error=# ERROR FUN2: args=[1, 2] error=# ERROR FUN1: args=[1, 2, 3] error=# ERROR FUN2: args=[1, 2, 3] error=# FUN1 args=[1, 2, 3, 4] -> fun1 {:a=>1, :b=>2, :c=>3, :d=>nil, :e=>4} FUN2 args=[1, 2, 3, 4] -> fun2 {:a=>1, :b=>2, :c=>3, :d=>nil, :e=>4} ERROR FUN1: args=[1, 2, 3, 4, 5] error=# ERROR FUN2: args=[1, 2, 3, 4, 5] error=# ERROR FUN1: args=[1, 2, 3, 4, 5, 6] error=# ERROR FUN2: args=[1, 2, 3, 4, 5, 6] error=# FUN1 args=[1, 2, [3, 4], 5] -> fun1 {:a=>1, :b=>2, :c=>3, :d=>4, :e=>5} FUN2 args=[1, 2, [3, 4], 5] -> fun2 {:a=>1, :b=>2, :c=>3, :d=>4, :e=>5} FUN1 args=[1, 2, [3, 4, 5], 6] -> fun1 {:a=>1, :b=>2, :c=>3, :d=>4, :e=>6} FUN2 args=[1, 2, [3, 4, 5], 6] -> fun2 {:a=>1, :b=>2, :c=>3, :d=>4, :e=>6} $ cat args.rb def fun1(a,b,(c,d),e) {a: a, b: b, c: c, d: d, e: e} end fun2 = lambda do |a,b,(c,d),e| {a: a, b: b, c: c, d: d, e: e} end [ [1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [1, 2, [3, 4], 5], [1, 2, [3, 4, 5], 6], ].each do |args| begin printf "FUN1 args=%p -> fun1 %p\n", args, fun1(*args) rescue Exception => e printf "ERROR FUN1: args=%p error=%p\n", args, e end begin printf "FUN2 args=%p -> fun2 %p\n", args, fun2[*args] rescue Exception => e printf "ERROR FUN2: args=%p error=%p\n", args, e end end Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/