Method arg names - maybe?

R

Ross Bamford

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') }
#=> [:eek:ne, :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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top