2013-05-17 8 views
7

Così, ho appena saputo che invece di cose come la scrittura:Ruby che prova a cogliere una nuova notazione. (Iniettare (:) vs selezionare (&: anche); il motivo per cui si ha &??)

[1,2,3,4,5].inject {|x,y| x + y} => 15 

Potrei scrivere

[1,2,3,4,5].inject(:+) => 15 

ho anche imparato che invece di scrivere

[1,2,3,4,5].select {|x| x.even?} => [2,4] 

potrei scrivere

[1,2,3,4,5].select(&:even?) => [2,4] 

La mia domanda è perché uno (seleziona) utilizza lo & e l'altro (inietto) no. Sono sicuro che lo e lo + sono trattati a simboli, ma mi piacerebbe chiarire il motivo per cui lo & viene utilizzato in uno e perché vengono utilizzati gli :.

Inoltre, sono a conoscenza che potrei fare queste notazioni su più di un semplice inject e select.

Grazie mille!

risposta

10

& l'operatore in questo caso converte un simbolo in un proc. Quindi il codice fa questo sotto il cofano:

[1,2,3,4,5].select {|elem| elem.send :even? } # => [2, 4] 

Attuazione inject metodo riconosce la necessità di queste specifiche metodo di scelta rapida e aggiunge un trattamento speciale per quando simbolo è passa come parametro. Quindi, in questo caso, fondamentalmente fa quello che fa l'operatore &.

perché uno (selezione) utilizza il & e l'altro (iniettare) non

fa perché nessuno implementato select in questo modo. Ruby è open source, potrebbero persino accettare la tua patch. Vai e correggi questo :)

P.S .: Ma se dipendesse da me, preferirei invece rimuovere la gestione speciale degli iniettori. Si sente un po 'ridondante e confusionario in presenza di Symbol#to_proc (è quello che usa l'operatore &).

+0

Vedo. Molto, molto interessante! In Ruby, trovo che molte cose sono molto semplici da fare, come ho fatto con la mia selezione. Sei andato avanti e hai scritto '{| elem | elem.send: even?} 'Questo è in sostanza ciò che il mio blocco sta facendo in background? Cambiare se stesso in quel formato e poi fare qualsiasi calcolo che è destinato a fare? Tanti modi diversi di fare cose in Ruby. Sono curioso. – David

+0

@David: sì, questo è ciò che 'select (&: even?)' Fa sotto il cofano. –

+1

@David non dimenticare di accettare la risposta, se effettivamente risponde alla domanda! – vgoff