Cosa &method(:function)
significa? Ad esempio, ho questa linea:
res = integrate(0, 1, a, &method(:function))
Cosa &method(:function)
significa? Ad esempio, ho questa linea:
res = integrate(0, 1, a, &method(:function))
Risposte:
Supponiamo di avere un metodo
def add_one(num)
num + 1
end
e una serie di stringhe
arr = ["1", "2"]
Vogliamo map
l'elenco di stringhe per i loro output corrispondenti da add_one
.
Per cominciare possiamo chiamare
nums = arr.map(&:to_i)
Questa è la stessa cosa di
nums = arr.map do |str|
str.to_i
end
Puoi vedere Cosa significa map (&: name) in Ruby? per maggiori informazioni su questo.
Tuttavia, non funzionerà per chiamare:
nums.map(&:add_one)
Perché? Perché i numeri non hanno un metodo incorporato add_one
. Quindi otterrai un NoMethodError
.
Quindi, anziché fornire solo un nome di metodo :add_one
, puoi passare un metodo associato method(:add_one)
:
nums.map(&method(:add_one))
Ora, anziché utilizzare ogni numero come ricevitore per il add_one
metodo, verranno utilizzati come argomenti . Quindi, è essenzialmente lo stesso di:
nums.map do |num|
add_one(num)
end
Per fare un altro esempio, confronta quanto segue:
[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
restituisce un limite Method
, non un UnboundMethod
. Il metodo è associato a un destinatario perché lo stai chiamando su un'istanza e quindi sa cos'è self
, mentre Module#instance_method
restituisce un UnboundMethod
perché non può sapere con quale istanza verrà utilizzato.
.instance_method
perché stavo solo passando per (imperfetto) memoria
method(:function)
è un messaggio inviato (a volte chiamato una chiamata di metodo ) al destinatario implicito (cioè self
). Sta inviando il messaggio method
al destinatario implicito (cioè self
), passando :function
come unico argomento.
:function
è un Symbol
letterale, cioè è la notazione letterale di a Symbol
. Symbol
è un tipo di dati che rappresenta "il nome di qualcosa".
L'operatore e commerciale prefisso unario &
"srotola" a Proc
in un blocco . Cioè ti permette di passare un punto Proc
dove è previsto un blocco . Se l'oggetto non è già a Proc
, verrà inviato il to_proc
messaggio che gli consente di convertirsi in a Proc
. (L'operatore è legale solo in un elenco di argomenti e solo per l'ultimo argomento. È il doppio del &
sigillo in un elenco di parametri, che "rotola" un blocco in un Proc
oggetto.)
Proc
è un tipo di dati che rappresenta il codice eseguibile. È la classe di libreria principale di Ruby per subroutine di prima classe.
Quindi, ciò che fa è chiamare il method
metodo self
con :function
come argomento, chiamare to_proc
il valore restituito, "srotolare" l' Proc
oggetto risultante in un blocco e passare quel blocco alla chiamata integrate
come se avessi scritto qualcosa come
res = integrate(0, 1, a) do
# something
end
Il method
metodo qui è molto probabilmente, il Object#method
metodo, che restituisce un oggetto associato Method
.
Quindi, tutto sommato, questo è in qualche modo equivalente a
res = integrate(0, 1, a) do |*args, &block|
function(*args, &block)
end
Ma espresso in quello che viene comunemente chiamato stile inutile .