# Method arg names - maybe?

**URL:** <https://www.ruby-forum.com/t/method-arg-names-maybe/52948>\
**Category:** Ruby\
**Created:** [January 21, 2006, 12:53am UTC](https://www.ruby-forum.com/t/method-arg-names-maybe/52948 "2006-01-21T00:53:44Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![ross\_b](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@ross\_b](https://www.ruby-forum.com/u/ross_b)\
**Post date:** [January 21, 2006, 12:53am UTC](https://www.ruby-forum.com/t/method-arg-names-maybe/52948/1 "2006-01-21T00:53:44Z")

</div>

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
