145 votes

En passant une méthode comme un paramètre en Ruby

Je suis en train de bricoler un peu avec Ruby. À cet effet, j’essaie de mettre en œuvre les algorithmes (donnée en Python) tiré du livre « Programmation Collective Intelligence » Ruby.

Dans le chapitre 8, l’auteur passe une méthode comme paramètre. Cela semble fonctionner en Python, mais pas en Ruby.

J’ai ici la méthode

et voulez appeler cela avec une autre méthode

Tout ce que j’ai obtenu est une erreur

119voto

Daniel Lucraft Points 3323

Les commentaires se référant aux blocs et les Procs sont corrects puisqu’ils sont plus habituels en Ruby. Mais vous pouvez passer à une méthode si vous voulez. Vous appelez pour obtenir la méthode et de l’appeler :

111voto

Alex Wayne Points 58113

Vous voulez un proc objet:

gaussian = Proc.new do |dist, *args|
  sigma = args.first || 10.0
  ...
end

def weightedknn(data, vec1, k = 5, weightf = gaussian)
  ...
  weight = weightf.call(dist)
  ...
end

Il suffit de noter que vous ne pouvez pas définir un argument par défaut dans un bloc de déclaration comme ça. Si vous avez besoin d'utiliser un splat et la configuration par défaut dans le proc code lui-même.


Ou, selon votre portée de tout cela, il peut être plus facile à passer dans un nom de méthode à la place.

def weightedknn(data, vec1, k = 5, weightf = :gaussian)
  ...
  weight = self.send(weightf)
  ...
end

Dans ce cas, vous êtes juste à l'appel d'une méthode est définie sur un objet plutôt que de passer dans un bloc de code. Selon la façon dont vous structurez cela, vous pouvez avoir besoin de remplacer self.send avec object_that_has_the_these_math_methods.send


Dernier mais non le moindre, vous pouvez accrocher un pâté de maisons de la méthode.

def weightedknn(data, vec1, k = 5)
  ...
  weight = 
    if block_given?
      yield(dist)
    else
      gaussian.call(dist)
    end
  end
  ...
end

wegihtedknn(foo, bar) do |dist|
  # square the dist
  dist * dist
end

Mais il semble que vous désirez de plus réutilisable morceaux de code ici.

58voto

Patrick Wong Points 111

Vous pouvez étudier ces codes :

 DEF t (a) un * 2 fin => nil def f (amusant) fun.call (10) fin => nil f (méthode ( : t)) => 20 

26voto

Chuck Points 138930

La façon normale de Ruby pour ce faire consiste à utiliser un bloc.

Il serait donc quelque chose comme :

Et utilisé comme :

Ce modèle est largement utilisé en Ruby.

17voto

Giovanni Points 1010

Vous pouvez utiliser le opérateur sur le instance de votre méthode pour convertir la méthode dans un bloc.

Exemple :

Plus de détails à http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html

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