variable que paso parametros parametro otro metodos metodo llamar herencia dentro con argumentos ruby-on-rails ruby

ruby on rails - que - ¿Hay alguna manera de acceder a los argumentos de método en Ruby?



ruby paso de parametros (10)

Nuevo en Ruby y ROR y me encanta cada día, así que aquí está mi pregunta ya que no tengo idea de cómo googlearlo (y lo he intentado :))

tenemos método

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

Entonces, estoy buscando la forma de que todos los argumentos pasen al método, sin enumerar cada uno. Como esto es Ruby, supongo que hay una manera :) si fuera Java, simplemente los enumeraría :)

La salida sería:

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


Esto puede ser útil ...

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


Antes de ir más lejos, estás pasando demasiados argumentos a foo. Parece que todos esos argumentos son atributos en un modelo, ¿correcto? Realmente debería estar pasando el objeto en sí. Fin del discurso.

Podría usar un argumento "splat". Pone todo en una matriz. Se vería así:

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


Desde Ruby 2.1 puede usar binding.local_variable_get para leer el valor de cualquier variable local, incluidos los parámetros del método (argumentos). Gracias a eso puedes mejorar la respuesta aceptada para evitar mal eval.

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


En Ruby 1.9.2 y posterior puede usar el método de parameters en un método para obtener la lista de parámetros para ese método. Esto devolverá una lista de pares que indica el nombre del parámetro y si es necesario.

p.ej

Si lo haces

def foo(x, y) end

entonces

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

Puede usar la variable especial __method__ para obtener el nombre del método actual. Entonces, dentro de un método, los nombres de sus parámetros se pueden obtener a través de

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

Luego, podría mostrar el nombre y el valor de cada parámetro con

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

Nota: dado que esta respuesta se escribió originalmente, en las versiones actuales de Ruby eval ya no se puede llamar con un símbolo. Para solucionar esto, se ha agregado un to_s explícito al to_s la lista de nombres de parámetros, es decir, parameters.map { |arg| arg[1].to_s } parameters.map { |arg| arg[1].to_s }


Esta es una pregunta interesante. Tal vez usando local_variables ? Pero debe haber una forma diferente a usar eval. Estoy buscando en 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


Parece que lo que esta pregunta está tratando de lograr podría hacerse con una gema que acabo de publicar, https://github.com/ericbeland/exception_details . Enumerará las variables locales y los vlaues (y las variables de instancia) de las excepciones rescatadas. Puede valer la pena mirar ...


Puede definir una constante como:

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

Y úsalo en tu código como:

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


Si cambia la firma del método, puede hacer algo como esto:

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

O:

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

En este caso, args interpolados u opts.values será una matriz, pero puede join si está en coma. Aclamaciones


Si necesita argumentos como Hash, y no quiere contaminar el cuerpo del método con la extracción complicada de parámetros, use esto:

def mymethod(firstarg, kw_arg1:, kw_arg2: :default) args = MethodArguments.(binding) # All arguments are in `args` hash now ... end

Solo agrega esta clase a tu proyecto:

class MethodArguments def self.call(ext_binding) raise ArgumentError, "Binding expected, #{ext_binding.class.name} given" unless ext_binding.is_a?(Binding) method_name = ext_binding.eval("__method__") ext_binding.receiver.method(method_name).parameters.map do |_, name| [name, ext_binding.local_variable_get(name)] end.to_h end end


Una forma de manejar esto es:

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