Enumerableモジュール

Enumerableモジュールは、繰り返し処理を行なうクラスのためのMixinです。
繰り返す処理とは例えば「sort」「map」「grep」などです。
これらの処理はeach関数を用いるので、EnumerableをMixinするときはeach関数を定義します。

class Vehicle                                                                   
  attr_reader :name, :wheels, :classes                                          
  def initialize(name, wheels, classes)                                         
    @name = name                                                                
    @wheels = wheels                                                            
    @classes = classes                                                          
  end                                                                           
end


class Group                                                                     
  include Enumerable                                                            
  def initialize                                                                
    @vehicles = []                                                              
  end                                                                           
  def add(vehicle)                                                              
    @vehicles << vehicle                                                        
    self                                                                        
  end                        
  def each                                                                      
    @vehicles.each do |vehicle|                                                 
      yield vehicle                                                             
    end                                                                         
  end                                                                           
end 


例では、GroupがEnumerableをMixinしてeachメソッドを定義しています。
eachメソッドでは、メンバであるvehiclesの配列の要素をブロックに渡すようにしています。
これにより、Groupにsortやmapやgrepメソッドが使用できるようになりました。

group = Group.new                                                               
group.add(Vehicle.new('Car',4,[:ground]))                                       
group.add(Vehicle.new('Truck',4,[:ground]))                                     
group.add(Vehicle.new('Boat',0,[:water]))                                       
group.add(Vehicle.new('Plane',0,[:air]))                                        
group.add(Vehicle.new('Helicopter',0,[:air]))                                   
group.add(Vehicle.new('Bike',2,[:ground]))                                      
group.add(Vehicle.new('Sea Plane',0,[:air, :ground]))                           


group.sort{|a,b| a.wheels <=> b.wheels}.each do |v|                             
  p v.wheels.to_s + ':' + v.name                                                
end
#"0:Sea Plane"
#"0:Helicopter"
#"0:Boat"
#"0:Plane"
#"2:Bike"
#"4:Truck"
#"4:Car"


                                                         
                                                                                
group.find_all{|v| v.name =~ /a/}.each do |v|                                   
  p v.name                                                                      
end                                                                             
#"Car"
#"Boat"
#"Plane"
#"Sea Plane"  

                                                                              
p group.map{|v| v.name.upcase } 
#["CAR", "TRUCK", "BOAT", "PLANE", "HELICOPTER", "BIKE", "SEA PLANE"]