From: Ross Bamford Date: 2006-02-05T06:18:19+09:00 Subject: Re: Extract hash into local variables? On Sat, 04 Feb 2006 19:46:03 -0000, csn wrote: > def foo2(args = {:a=>1, :b=>2, :c=>3}) > a,b,c = args.values > > puts a,b,c > end > Careful with that, I think hash order is undefined? I was playing a bit with this stuff recently and came up with this: class Method def arg_names catch(:traced) do dummy_args = [nil] dummy_args *= self.arity unless self.arity < 0 set_trace_func lambda { |event, file, line, id, bdng, cls| if event == 'call' set_trace_func nil throw(:traced, eval('local_variables',bdng).map { |lv| lv.intern }) end } self.call(*dummy_args) # if we get here, call is bust set_trace_func nil raise "No ruby method call in block" end end def hcall(hash, &blk) names = arg_names.reject { |n| n =~ /^(.*proc|bl(oc)?k)$/ } call(*names.map { |n| hash[n] or raise "Missing argument" }, &blk) end end def foo(a,b,c) p [a,b,c] end method(:foo).hcall(:c => 'C', :a => 'A', :b => 'B') # => ["A", "B", "C"] but it's block argument handling is very weak and it can't handle methods implemented in C. Better to just wait for Ruby 2.0. Personally, I've never once missed them anyway. -- Ross Bamford - rosco@roscopeco.remove.co.uk