115 votes

Existe-t-il un moyen d'accéder aux arguments de méthodes dans Ruby?

Nouveau pour Ruby and ROR et l’aimer tous les jours, alors voici ma question car je n’ai pas idée de la façon de le rechercher sur Google (et j’ai essayé :))

nous avons la méthode

 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
 

Donc, ce que je recherche un moyen d’obtenir tous les arguments passés à la méthode, sans les lister tous. Puisqu'il s'agit de Ruby, je suppose qu'il y a un moyen :) s'il était java, je les énumérerais simplement :)

La sortie serait:

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

169voto

mikej Points 30224

En Ruby 1.9.2 vous pouvez utiliser l' parameters méthode sur une méthode pour obtenir la liste des paramètres de la méthode. Cela retournera une liste de paires en indiquant le nom du paramètre et si c'est nécessaire.

par exemple

Si vous ne

def foo(x, y)
end

alors

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

Vous pouvez utiliser la variable spéciale __method__ pour obtenir le nom de la méthode actuelle. Donc, à l'intérieur d'une méthode les noms de ses paramètres peuvent être obtenus via

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

Vous pouvez ensuite afficher le nom et la valeur de chaque paramètre avec

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

20voto

Arun Kumar Arjunan Points 4437

Une façon de gérer cela est:

 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
 

8voto

Raffaele Points 10209

C'est une question intéressante. Peut-être en utilisant local_variables ? Mais il doit y avoir un autre moyen que d'utiliser eval. Je cherche dans le noyau 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
 

3voto

Al Johri Points 196

Vous pouvez définir une constante telle que:

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

Et utilisez-le dans votre code comme:

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

2voto

Tom L Points 2200

Avant d’aller plus loin, vous passez trop d’arguments à foo. Il semble que tous ces arguments sont des attributs d'un modèle, n'est-ce pas? Vous devriez vraiment passer l'objet lui-même. Fin du discours

Vous pouvez utiliser un argument "splat". Il met tout dans un tableau. Cela ressemblerait à:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X