From: Josh Cheek Date: 2010-06-17T04:03:23+09:00 Subject: Re: strange behaviour if exploding parameters --0016364efa2613c61404892a60f0 Content-Type: text/plain; charset=ISO-8859-1 On Wed, Jun 16, 2010 at 9:01 AM, Jarmo Pertman wrote: > Hello! > > I've just happened to find strange behaviour when trying to explode > parameters. > > Why doesn't it work? > irb(main):007:0> lambda {|*parameters| *parameters.class} > SyntaxError: compile error > (irb):7: syntax error, unexpected '}', expecting tCOLON2 or '[' or '.' > from (irb):7 > from :0 > > > class is Array if 0 or more parameters given > irb(main):009:0> l = lambda {|*parameters| p *parameters.class} > => # > irb(main):010:0> l[] > Array > => nil > > > class is Array if some parameters given > irb(main):012:0> l = lambda {|*parameters| x = *parameters; p x.class} > => # > irb(main):013:0> l[1,2] > Array > => nil > > > class is NilClass instead of Array? > irb(main):014:0> l[] > NilClass > => nil > > Any ideas why class is NilClass instead of Array if *parameters is > assigned to local variable? I'd expect it to be always an Array and if > no parameters given then an empty Array. > > Best Regards, > Jarmo > -- > Posted via http://www.ruby-forum.com/. > > Hi, I think you might be a bit confused about how * works in your param list. It will aggregate all the params into a single array: lambda { |*params| params }.call 1 , 2 , 3 # => [1, 2, 3] So you can call class on it lambda { |*params| params.class }.call 1 , 2 , 3 # => Array return is a method invocation (at least in my mind) so you can "explode" the brackets here too, and it becomes like "return 1 , 2 , 3" which is syntactically the same as "call 1 , 2 , 3" lambda { |*params| return *params }.call 1 , 2 , 3 # => [1, 2, 3] But there are two things that don't really make sense. "1 , 2 , 3" all by itself is not valid Ruby. Leaving it on its own line like this lambda { |*params| *params }.call 1 , 2 , 3 # => syntax error Is like saying this lambda { |*params| 1 , 2 , 3 }.call 1 , 2 , 3 # => syntax error Since that is not valid, then what does it mean to say *params.class ? Well, first of all, the .class is evaluated first (not sure how to say that, "higher binding" maybe?) The class is an Array. so this becomes "*Array" which is probably not what you want, and only works, again, when passing it to return. lambda { |*params| return *params.class }.call 1 , 2 , 3 # => Array lambda { |*params| *params.class }.call 1 , 2 , 3 # => syntax error So, in summary, I think this is what you were looking for: lambda { |*params| params.class }.call 1 , 2 , 3 # => Array --0016364efa2613c61404892a60f0--