2011-08-28 25 views
45

Tôi có một lớp được gọi là Note, bao gồm một biến mẫu được gọi là time_spent. Tôi muốn có thể làm một việc như sau:Tôi làm cách nào để sử dụng mixin Enumerable trong lớp học của mình?

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

Điều này có thể bằng cách trộn trong Enumerable module? Tôi biết bạn có nghĩa vụ phải thêm include Enumerable vào lớp và sau đó xác định phương thức each, nhưng phương pháp mỗi phải là một lớp hoặc phương pháp thể hiện? Điều gì xảy ra trong phương thức each?

Tôi đang sử dụng của Ruby 1.9.2

+1

Xin lỗi nếu câu hỏi của tôi là tránh khỏi thất bại, nhưng vì 'current_user.notes' đã là một mảng, có nghĩa là nó đã bao gồm Enumerable, tại sao bạn cần phải làm gì hơn? Ví dụ của bạn có thể đã chạy với một thay đổi nhỏ: 'current_user.notes.inject (0) {| total_time_spent, note | total_time_spent + note.time_spent} ' –

+0

Hoặc nếu bạn đang sử dụng đường ray:' current_user.notes.sum (&: time_spent) ' – aidan

Trả lời

75

Nó dễ dàng, chỉ bao gồm các module Enumerable và xác định một phương pháp each dụ, mà thường xuyên hơn không sẽ chỉ sử dụng phương pháp each một số khác lớp của. Dưới đây là ví dụ thực sự được đơn giản hóa:

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) 

Để biết thêm thông tin, tôi đề xuất bài viết sau: Ruby Enumerable Magic: The Basics.

Trong ngữ cảnh câu hỏi của bạn, nếu những gì bạn vạch trần thông qua người truy cập đã là bộ sưu tập, có thể bạn không cần phải bận tâm với việc bao gồm Enumerable.

+0

bạn cũng có thể nói' yield member' thay vì 'block.call (member)' –

+2

Khi tôi sử dụng các đối số khối rõ ràng Tôi thích làm việc với các đối tượng proc. Cá nhân tôi muốn sử dụng '[]' bí danh cho 'call' bình thường (' block [member] '), nhưng nghĩ rằng có thể gây nhầm lẫn cho OP. –

+11

tại sao không đơn giản là '@ members.each (& block)'? – tokland

1

Các Enumerable tài liệu sais sau:

Các Enumerable mixin cung cấp các lớp học tập với một số phương pháp traversal và tìm kiếm, và với khả năng sắp xếp. Lớp phải cung cấp phương thức mỗi, cho phép các thành viên liên tiếp là bộ sưu tập. Nếu Enumerable # max, #min, hoặc #sort được sử dụng, các đối tượng trong bộ sưu tập cũng phải thực hiện một ý nghĩa điều hành < =>, như những phương pháp này dựa trên một trật tự giữa các thành viên của bộ sưu tập.

Điều này có nghĩa việc thực hiện mỗi< => sẽ làm các trick.

Xem: Enumerable

Các vấn đề liên quan