Forum: Ruby Method arg names - maybe?

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Ross B. (Guest)
on 2006-01-21 01:53
(Received via mailing list)

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 topic is locked and can not be replied to.