Method arg names - maybe?


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)[]) { |ary, v| ary << v.intern })

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”

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

c =

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 { }
-: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…?


This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs