Que veut &method(:function)dire? Par exemple, j'ai cette ligne:
res = integrate(0, 1, a, &method(:function))
Que veut &method(:function)dire? Par exemple, j'ai cette ligne:
res = integrate(0, 1, a, &method(:function))
Réponses:
Disons que nous avons une méthode
def add_one(num)
num + 1
end
et un tableau de chaînes
arr = ["1", "2"]
Nous voulons mapla liste des chaînes à leurs sorties correspondantes de add_one.
Pour commencer, nous pouvons appeler
nums = arr.map(&:to_i)
C'est la même chose que
nums = arr.map do |str|
str.to_i
end
Vous pouvez voir Que signifie la carte (&: nom) dans Ruby? pour plus d'informations à ce sujet.
Cependant, cela ne fonctionnera pas d'appeler:
nums.map(&:add_one)
Pourquoi? Parce que les nombres n'ont pas de méthode intégrée add_one. Vous obtiendrez donc un NoMethodError.
Ainsi, plutôt que de fournir simplement un nom de méthode, :add_one vous pouvez passer une méthode liée method(:add_one) :
nums.map(&method(:add_one))
Maintenant, plutôt que chaque num étant utilisé comme récepteur pour la add_oneméthode, ils seront utilisés comme arguments . Donc, c'est essentiellement la même chose que:
nums.map do |num|
add_one(num)
end
Pour donner un autre exemple, comparez les éléments suivants:
[1].map(&:puts)
# this is the same as [1].map { |num| num.puts }
# it raises NoMethodError
[1].map(&method(:puts))
# this is the same as [1].map { |num| puts num }
# it prints 1 successfully
Object#methodretourne une borne Method , pas une UnboundMethod. La méthode est liée à un récepteur parce que vous l'appelez sur une instance et elle sait donc ce qu'est self, alors qu'elle Module#instance_methodretourne une UnboundMethodcar elle ne peut pas savoir avec quelle instance elle va être utilisée.
.instance_methodparce que je passais juste par la mémoire (défectueuse)
method(:function)est un message envoyé (parfois appelé appel de méthode ) au récepteur implicite (ie self). Il envoie le message methodau récepteur implicite (c'est-à-dire self), en le passant :functioncomme seul argument.
:functionest un Symbollittéral, c'est-à-dire qu'il s'agit de la notation littérale de a Symbol. Symbolest un type de données représentant "le nom de quelque chose".
L'opérateur préfixe unaire esperluette &"déroule" un Procdans un bloc . C'est à dire qu'il vous permet de passer un Procoù un bloc est attendu. Si l'objet n'est pas déjà un Proc, il recevra le to_procmessage lui permettant de se convertir en a Proc. (L'opérateur n'est légal que dans une liste d'arguments et uniquement pour le dernier argument. C'est le double du &sigil dans une liste de paramètres, qui "roule" un bloc dans un Procobjet.)
Procest un type de données représentant du code exécutable. C'est la classe de bibliothèque principale de Ruby pour les sous-programmes de première classe.
Donc, ce que cela fait, c'est appeler la methodméthode selfavec :functioncomme argument, appeler to_procla valeur de retour, "dérouler" l' Procobjet résultant dans un bloc et passer ce bloc à l'appel integratecomme si vous aviez écrit quelque chose comme
res = integrate(0, 1, a) do
# something
end
La methodméthode ici est très probablement, la Object#methodméthode, qui renvoie un objet lié Method .
Donc, dans l'ensemble, cela équivaut quelque peu à
res = integrate(0, 1, a) do |*args, &block|
function(*args, &block)
end
Mais exprimé dans ce qu'on appelle communément le style sans point .