From: Ross Bamford Date: 2006-01-21T08:15:36+09:00 Subject: Method arg names - maybe? Hi, I noticed a couple of questions about getting names of method arguments, and the general consensus seems that it's not possible to do that. I wonder if this indirect way might be a) safe and b) workable? def arg_names endcc = nil set_trace_func lambda { |event, file, line, id, binding, classname| if event == 'call' lvs = eval('local_variables', binding) endcc.call(lvs.inject([]) { |ary, v| ary << v.intern }) end } # if yield completes, no 'call' was made names = callcc { |endcc| yield; nil } set_trace_func nil names or raise ArgumentError, "No Ruby method call in block" end It appears to work reasonably well in limited testing, e.g.: class TestClz def meth(one, two = 'three'); puts "Meth: #{one}, #{two}"; end def beth(*args, &blk); puts "Beth: #{args.inspect}"; end def ceth; puts "Ceth: (no args)"; end end c = TestClz.new p arg_names { c.meth('dummy') } > #=> [:one, :two] p arg_names { c.beth('one', 'two', 'three') } > #=> [:args, :blk] p arg_names { c.ceth } > #=> [] p arg_names { String.new } > -:26:in `arg_names': No Ruby method call in block (ArgumentError) It does require a dummy method call to get the information, but none of the method's code is actually executed so it shouldn't cause problems I think (?). I don't know though whether it could cause other problems by circumventing the call like that...? Cheers, Ross -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk