2011-08-28 11 views
45

Ho una classe chiamata Note, che include una variabile di istanza denominata time_spent. Voglio essere in grado di fare qualcosa del genere:Come uso il mixin Enumerable nella mia classe?

current_user.notes.inject{|total_time_spent,note| total_time_spent + note.time_spent} 

Questo è possibile miscelando nel Enumerable module? So che dovresti aggiungere include Enumerable alla classe e quindi definire un metodo each, ma il metodo dovrebbe essere ogni classe o istanza? Cosa succede nel metodo each?

sto usando rubino 1.9.2

+1

Mi scusi se la mia domanda è all'oscuro, ma dal momento che 'current_user.notes' è già una matrice, il che significa che comprende già Enumerable, perché avete bisogno di fare qualcosa di più? Il tuo esempio può già essere eseguito con una piccola modifica: 'current_user.notes.inject (0) {| total_time_spent, note | total_time_spent + note.time_spent} ' –

+0

Oppure se stai usando le rotaie:' current_user.notes.sum (&: time_spent) ' – aidan

risposta

75

E 'facile, basta includere il modulo Enumerable e definire un metodo di each esempio, che il più delle volte non basta usare il metodo each di qualche altra classe. Ecco un esempio molto semplificato:

class ATeam 
    include Enumerable 

    def initialize(*members) 
    @members = members 
    end 

    def each(&block) 
    @members.each do |member| 
     block.call(member) 
    end 
    # or 
    # @members.each(&block) 
    end 
end 

ateam = ATeam.new("Face", "B.A. Barracus", "Murdoch", "Hannibal") 
#use any Enumerable method from here on 
p ateam.map(&:downcase) 

Per ulteriori informazioni, vi consiglio il seguente articolo: Ruby Enumerable Magic: The Basics.

Nel contesto della domanda, se ciò che si espone tramite una funzione di accesso è già una raccolta, probabilmente non è necessario preoccuparsi di includere Enumerable.

+0

potresti anche dire' yield member' invece di 'block.call (member)' –

+2

When I usa argomenti di blocco espliciti Preferisco lavorare con gli oggetti proc. Personalmente userei l'alias '[]' per 'call' normalmente (' block [member] '), ma ho pensato che potrebbe essere fonte di confusione per OP. –

+11

perché non semplicemente '@ members.each (& block)'? – tokland

1

I enumerabili documentazioni Sais il seguente:

Il mixin Enumerable fornisce classi di insiemi con diversi metodi attraversamento e la ricerca, e con la possibilità di ordinare. La classe deve fornire un metodo ogni, che restituisce i membri successivi di della raccolta. Se viene utilizzato Enumerable # max, #min, o #Spostare, gli oggetti della collezione devono anche attuare un significativo operatore < =>, come questi metodi si basano su un ordinamento tra i membri della collezione.

Ciò significa attuare ogni e < => farà il trucco.

See: Enumerable

Problemi correlati