有没有办法在Ruby中访问方法参数?

新的Ruby和ROR和爱它每天,所以这里是我的问题,因为我不知道如何谷歌它(我已经试过:))

我们有方法

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

所以我正在寻找方式来获取所有parameter passing给方法,没有列出每一个。 因为这是ruby,我认为有一种方法:)如果是Java我只是列出他们:)

输出将是:

 Method has failed, here are all method arguments {"Mario", "Super", 40, true, true} 

在Ruby 1.9.2及更高版本中,您可以使用方法的parameters方法来获取该方法的参数列表。 这将返回一个表示参数名称和是否需要的对列表。

例如

如果你这样做

 def foo(x, y) end 

然后

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

您可以使用特殊variables__method__来获取当前方法的名称。 因此,在一个方法中,其参数的名称可以通过

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

然后您可以显示每个参数的名称和值

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

注意:因为这个答案最初是写的,所以在当前版本的Ruby eval中不能再用符号来调用。 为了解决这个问题,在构build参数名称列表(如parameters.map { |arg| arg[1].to_s }时添加了显式的to_s parameters.map { |arg| arg[1].to_s }

由于Ruby 2.1可以使用binding.local_variable_get来读取任何局部variables的值,包括方法参数(参数)。 多亏了这一点,你可以改善接受的答案,以避免 邪恶 EVAL。

 def foo(x, y) method(__method__).parameters.map do |_, name| binding.local_variable_get(name) end end foo(1, 2) # => 1, 2 

处理这个问题的一个方法是:

 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 

这是个有趣的问题。 也许使用local_variables ? 但是除了使用eval之外,还有一种方法。 我在找内核文档

 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 

你可以定义一个常量,例如:

 ARGS_TO_HASH = "method(__method__).parameters.map { |arg| arg[1].to_s }.map { |arg| { arg.to_sym => eval(arg) } }.reduce Hash.new, :merge" 

并在你的代码中使用它:

 args = eval(ARGS_TO_HASH) another_method_that_takes_the_same_arguments(**args) 

在我进一步讨论之前,你将太多的论据传递给foo。 它看起来像所有这些参数是一个模型的属性,是正确的? 你应该真的传递对象本身。 讲话结束。

你可以使用“splat”参数。 它把所有东西都塞进一个数组中。 它看起来像:

 def foo(*bar) ... log.error "Error with arguments #{bar.joins(', ')}" end 

如果你要改变方法签名,你可以这样做:

 def foo(*args) # some code # error happens here logger.error "Method has failed, here are all method arguments #{args}" end 

要么:

 def foo(opts={}) # some code # error happens here logger.error "Method has failed, here are all method arguments #{opts.values}" end 

在这种情况下,内插argsopts.values将是一个数组,但是如果使用逗号,则可以join 。 干杯

似乎这个问题试图完成可以用我刚刚发布的gem, https://github.com/ericbeland/exception_details 。 它将列出来自救出的exception的本地variables和vlaue(和实例variables)。 也许值得一瞧…

这可能有帮助…

  def foo(x, y) args(binding) end def args(callers_binding) callers_name = caller[0][/`.*'/][1..-2] parameters = method(callers_name).parameters parameters.map { |_, arg_name| callers_binding.local_variable_get(arg_name) } end