Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to access method arguments in Ruby?

People also ask

How are arguments passed in Ruby?

In ruby, arguments inside a method are passed by reference Thus, if we will change an object inside the method, then it will be changed also outside the method.

What is * args in Ruby?

In the code you posted, *args simply indicates that the method accepts a variable number of arguments in an array called args . It could have been called anything you want (following the Ruby naming rules, of course).

How do you call a method in an argument?

When we call a method, the actual arguments in method call has to be passed to the formal parameters of method definition. This process is called passing parameters in java or simply called passing arguments to the method.

Can you call a method inside a method Ruby?

In short: no, Ruby does not support nested methods.


In Ruby 1.9.2 and later you can use the parameters method on a method to get the list of parameters for that method. This will return a list of pairs indicating the name of the parameter and whether it is required.

e.g.

If you do

def foo(x, y)
end

then

method(:foo).parameters # => [[:req, :x], [:req, :y]]

You can use the special variable __method__ to get the name of the current method. So within a method the names of its parameters can be obtained via

args = method(__method__).parameters.map { |arg| arg[1].to_s }

You could then display the name and value of each parameter with

logger.error "Method failed with " + args.map { |arg| "#{arg} = #{eval arg}" }.join(', ')

Note: since this answer was originally written, in current versions of Ruby eval can no longer be called with a symbol. To address this, an explicit to_s has been added when building the list of parameter names i.e. parameters.map { |arg| arg[1].to_s }


Since Ruby 2.1 you can use binding.local_variable_get to read value of any local variable, including method parameters (arguments). Thanks to that you can improve the accepted answer to avoid evil eval.

def foo(x, y)
  method(__method__).parameters.map do |_, name|
    binding.local_variable_get(name)
  end
end

foo(1, 2)  # => 1, 2

One way to handle this is:

def foo(*args)
    first_name, last_name, age, sex, is_plumber = *args
    # some code
    # error happens here
    logger.error "Method has failed, here are all method arguments #{args.inspect}"    
end

This is an interesting question. Maybe using local_variables? But there must be a way other than using eval. I'm looking in Kernel doc

class Test
  def method(first, last)
    local_variables.each do |var|
      puts eval var.to_s
    end
  end
end

Test.new().method("aaa", 1) # outputs "aaa", 1