Yehuda Katz wrote: > It seems like this is happening because the |x,| syntax is getting > errantly parsed as an masgn, and treated as such as a block, but somehow > treated as an lasgn in the standlone lambda case. Am I misunderstanding > something? I was also confused by this behavior so I made a table of the differences between blocks and lambdas: arr = [] arr << " lambda{|x,y|x}" arr << " lambda{|x,| x}" arr << " lambda{|x| x}" arr << "Proc.new{|x,y|x}" arr << "Proc.new{|x,| x}" arr << "Proc.new{|x| x}" arr.each do |label| fn = eval(label) (1..2).each do |nb_args| args = (1..nb_args).to_a res = fn.call(args) rescue :err puts "%s.call( %-6s ) -> %s" % [label, args.inspect, res.inspect] res = fn.call(*args) rescue :err puts "%s.call(*%-6s ) -> %s" % [label, args.inspect, res.inspect] end end lambda{|x,y|x}.call( [1] ) -> :err lambda{|x,y|x}.call(*[1] ) -> :err lambda{|x,y|x}.call( [1, 2] ) -> :err lambda{|x,y|x}.call(*[1, 2] ) -> 1 lambda{|x,| x}.call( [1] ) -> [1] lambda{|x,| x}.call(*[1] ) -> 1 lambda{|x,| x}.call( [1, 2] ) -> [1, 2] lambda{|x,| x}.call(*[1, 2] ) -> :err lambda{|x| x}.call( [1] ) -> [1] lambda{|x| x}.call(*[1] ) -> 1 lambda{|x| x}.call( [1, 2] ) -> [1, 2] lambda{|x| x}.call(*[1, 2] ) -> [1, 2] + warning (ruby1.8) -> :err (ruby1.9) Proc.new{|x,y|x}.call( [1] ) -> 1 Proc.new{|x,y|x}.call(*[1] ) -> 1 Proc.new{|x,y|x}.call( [1, 2] ) -> 1 Proc.new{|x,y|x}.call(*[1, 2] ) -> 1 Proc.new{|x,| x}.call( [1] ) -> 1 Proc.new{|x,| x}.call(*[1] ) -> 1 Proc.new{|x,| x}.call( [1, 2] ) -> 1 Proc.new{|x,| x}.call(*[1, 2] ) -> 1 Proc.new{|x| x}.call( [1] ) -> [1] Proc.new{|x| x}.call(*[1] ) -> 1 Proc.new{|x| x}.call( [1, 2] ) -> [1, 2] Proc.new{|x| x}.call(*[1, 2] ) -> [1, 2] + warning (ruby1.8) -> 1 (ruby1.9) So I think it has to do with blocks using multiple-assignment semantics and lambdas using function-arguments semantics. Since there is no such thing as "def foo(x,)" then "lambda{|x,|" is considered as the equivalent of "def foo(x)". Do I have it wrong? -- Daniel