有没有办法在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
在这种情况下,内插args
或opts.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