From: Robert Klemme Date: 2006-01-10T01:58:02+09:00 Subject: Re: hash as paramerter container Sch�le Daniel wrote: > Hello all, > > I am looking for Ruby equivalent for this Python Code > > >>> def foo(a,b,c): > ... print "a is ", a > ... print "b is ", b > ... print "c is ", c > ... > >>> h = {"c":3, "a":1, "b":2} > >>> > >>> foo > > >>> foo(**h) > a is 1 > b is 2 > c is 3 > > my first try > > => {"c"=>333, :b=>2, :a=>1} > irb(main):017:0> def foo a,b,c > irb(main):018:1> puts "a is #{a}" > irb(main):019:1> puts "b is #{b}" > irb(main):020:1> puts "c is #{c}" > irb(main):021:1> end > => nil > irb(main):022:0> foo *h > a is c333 > b is b2 > c is a1 > => nil > > > this seem to replace (or substituate) the parameters expected by foo > in the order of hash. And since hash has no order (in both languages) > it's a random replacement. > > Is there a trick I don't know about? I don't know Python but I assume that foo(**h) assigns hash entries to function arguments. Ruby cannot do this because parameter names are lost at runtime. Here's what you can do: def foo(*a) case a.length when 1 a[0].each {|k,v| puts "#{k} is #{v}"} when 3 puts "a is #{a[0]}" puts "b is #{a[1]}" puts "c is #{a[2]}" else raise ArgumentError, "wrong number of arguments" end end >> foo(1,2,3) a is 1 b is 2 c is 3 => nil >> foo(:x=>1, :y=>32, :z=>4) y is 32 z is 4 x is 1 => {:y=>32, :z=>4, :x=>1} >> foo(1,2,3,4) RuntimeError: Illegal Call from (irb):24:in `foo' from (irb):29 from :0 But generally you would decide whether you use a hash or individual parameters. You could go through some hoops to retrofit something on Ruby that will behave approximately like Python does but I won't be fast or elegant and I guess there would be some limitations. But Ruby 2 is will introduce new functionality here (named parameters / arguments); it might then be possible to do what you know from Python. HTH Kind regards robert