Cosa significa `& method (: function)`?


15

Cosa &method(:function)significa? Ad esempio, ho questa linea:

res = integrate(0, 1, a, &method(:function))

Due risposte eccellenti (finora). Sei fortunato!
Cary Swoveland,

Risposte:


13

Supponiamo di avere un metodo

def add_one(num)
  num + 1
end

e una serie di stringhe

arr = ["1", "2"]

Vogliamo mapl'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_onemetodo, 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

Nitpick: Object#methodrestituisce 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_methodrestituisce un UnboundMethodperché non può sapere con quale istanza verrà utilizzato.
Jörg W Mittag,

@ JörgWMittag Ok, grazie per la correzione, hai ragione, devo averlo mescolato .instance_methodperché stavo solo passando per (imperfetto) memoria
massimo pleaner

10

method(:function)è un messaggio inviato (a volte chiamato una chiamata di metodo ) al destinatario implicito (cioè self). Sta inviando il messaggio methodal destinatario implicito (cioè self), passando :functioncome unico argomento.

:functionè un Symbolletterale, 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 Procin un blocco . Cioè ti permette di passare un punto Procdove è previsto un blocco . Se l'oggetto non è già a Proc, verrà inviato il to_procmessaggio 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 Procoggetto.)

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 methodmetodo selfcon :functioncome argomento, chiamare to_procil valore restituito, "srotolare" l' Procoggetto risultante in un blocco e passare quel blocco alla chiamata integratecome se avessi scritto qualcosa come

res = integrate(0, 1, a) do
  # something
end

Il methodmetodo qui è molto probabilmente, il Object#methodmetodo, 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 .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.