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 map
la 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_one
mé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#method
retourne 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_method
retourne une UnboundMethod
car elle ne peut pas savoir avec quelle instance elle va être utilisée.
.instance_method
parce 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 method
au récepteur implicite (c'est-à-dire self
), en le passant :function
comme seul argument.
:function
est un Symbol
littéral, c'est-à-dire qu'il s'agit de la notation littérale de a Symbol
. Symbol
est un type de données représentant "le nom de quelque chose".
L'opérateur préfixe unaire esperluette &
"déroule" un Proc
dans un bloc . C'est à dire qu'il vous permet de passer un Proc
où un bloc est attendu. Si l'objet n'est pas déjà un Proc
, il recevra le to_proc
message 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 Proc
objet.)
Proc
est 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 method
méthode self
avec :function
comme argument, appeler to_proc
la valeur de retour, "dérouler" l' Proc
objet résultant dans un bloc et passer ce bloc à l'appel integrate
comme si vous aviez écrit quelque chose comme
res = integrate(0, 1, a) do
# something
end
La method
méthode ici est très probablement, la Object#method
mé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 .