I'm trying to figure out how the current implementation of argument
definition and passing is working. So I produced a test case. It runs fine
but there's one thing I can't understand. How one can call the method
which's argument definition is parsed with following yacc definition:

  f_args    : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg

In my test case the first call to foo is working fine, but the second don't
have any value for the the optional argument so Ruby leaks first entry from
the *rest and substitute the optional argument with it. Is there a call
format which works in this case or should the parsing be changed so that
f_optarg and f_rest_arg can't be present at the same time?

(Dave, only one foo this time. :)

def foo(static, optional=1, *rest, &block)
  named=rest.pop if rest[-1].kind_of? Hash

  puts "Static:"
  puts "#{static.type} #{static}"

  puts "\nOptional:"
  puts "#{optional.type} #{optional}"

  puts "\nRest:"
  for var in rest
    puts "#{var.type} #{var}"
  end

  puts "\nNamed:"
  named.each do |key, value|
    puts "#{key}=#{value}"
  end

  puts "\nand block" if iterator?
end

foo('normal','optional', 'list','stored','vars', 'named'=>'var') do 
  puts "block" 
end

puts "==============="

foo('normal', 'list','stored','vars', 'named'=>'var') do 
  puts "block" 
end

#################

And the output:

Static:
String normal

Optional:
String optional

Rest:
String list
String stored
String vars

Named:
named=var

and block
===============
Static:
String normal

Optional:
String list

Rest:
String stored
String vars

Named:
named=var

and block