def parse_string(s, arg_split:',', valuesep: ':', default: nil,
				opt_valuesep: '=', opt_default: true, opts_split: '!',
				globalopts_separator: '!!', globopts_split: arg_split, 
				globalopts_valuesep: opt_valuesep, globalopts_default: opt_default)
			r={values: {}, local_opts: {}, global_opts: {}, opts: {}}
			args,*globopts=s.split(globalopts_separator)
			globopts.map {|g| g.split(globopts_split)}.flatten.each do |g|
				name,value=parse_namevalue(g, sep: globalopts_valuesep, default: globalopts_default)
				r[:global_opts][name]=value
			end
			args.split(arg_split).each do |arg|
				arg,*localopts=arg.split(opts_split)
				name,value=parse_namevalue(arg, sep: valuesep, default: default)
				r[:values][name]=value
				r[:local_opts][name]={}
				localopts.each do |o|
					oname,ovalue=parse_namevalue(o, sep: opt_valuesep, default: opt_default)
					r[:local_opts][name][oname]=ovalue
				end
				r[:local_opts].each do |name,hash|
					r[:opts][name]=r[:local_opts][name].dup
					r[:global_opts].each do |k,v|
						r[:opts][name][k]||=v
					end
				end
			end
			return r
		end
def parse_string(s, arg_split:',', valuesep: ':', default: nil,
				opt_valuesep: '=', opt_default: true, opts_split: '!',
				globalopts_separator: '!!', globopts_split: arg_split, 
				globalopts_valuesep: opt_valuesep, globalopts_default: opt_default)
			r={values: {}, local_opts: {}, global_opts: {}, opts: {}}
			args,*globopts=s.split(globalopts_separator)
			globopts.map {|g| g.split(globopts_split)}.flatten.each do |g|
				name,value=parse_namevalue(g, sep: globalopts_valuesep, default: globalopts_default)
				r[:global_opts][name]=value
			end
			args.split(arg_split).each do |arg|
				arg,*localopts=arg.split(opts_split)
				name,value=parse_namevalue(arg, sep: valuesep, default: default)
				r[:values][name]=value
				r[:local_opts][name]={}
				localopts.each do |o|
					oname,ovalue=parse_namevalue(o, sep: opt_valuesep, default: opt_default)
					r[:local_opts][name][oname]=ovalue
				end
				r[:local_opts].each do |name,hash|
					r[:opts][name]=r[:local_opts][name].dup
					r[:global_opts].each do |k,v|
						r[:opts][name][k]||=v
					end
				end
			end
			return r
		end
takes a string as "name:value!option1=ploum!option2=plam,name2:value2!!globalopt=plim,globalopt2=plam!!globalopt3=plom,globalopt4=plim"
and return the hash
{values: {name: value, name2: value2},
 local_opts: {name: {option1:ploum,option2:plam}},
 global_opts: {globalopt: plim, globalopt2: plam},
 opts: {name: {option1:ploum,option2:plam,globalopt: plim, globalopt2: plam}, name2:{{globalopt: plim, globalopt2: plam}}}

Algo: split on 'args!!globopts'
  globopts are split on ',' or '!!'
  args are split on ',' into parameters
  parameters are split on 'args!local_opts'
  args are split on 'name:value' using parse_namevalue
  local_opts are splits on 'opt=value" using parse_namevalue