O Módulo Enumerable
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 30 de 57.
Enumerable é o módulo por trás dos métodos de coleção de arrays e hashes. Uma classe que define each, produzindo seus elementos um por um, e inclui Enumerable obtém map, select, count, sort_by, min_by, sum, include? e dezenas de outros:
class Playlist
include Enumerable
def initialize(*songs)
@songs = songs
end
def each
@songs.each { |song| yield song }
end
end
list = Playlist.new("Intro", "Dune", "Outro")
puts list.map(&:upcase).join(", ")
puts list.select { |s| s.size > 4 }.inspect
puts list.count
puts list.include?("Dune")Saída:
INTRO, DUNE, OUTRO
["Intro", "Outro"]
3
trueyield passa um valor para o bloco que o chamador forneceu a each. A classe decide o que é um elemento, por exemplo, uma linha de texto, um par de valores ou um de seus próprios objetos:
class Inventory
include Enumerable
def initialize
@stock = { "apple" => 3, "pear" => 0, "plum" => 7 }
end
def each
@stock.each { |name, qty| yield name, qty }
end
end
inv = Inventory.new
p inv.select { |_, qty| qty.positive? }.map(&:first)
p inv.max_by { |_, qty| qty }Saída:
["apple", "plum"]
["plum", 7]Os elementos não precisam ser armazenados. each pode calculá-los à medida que avança, e métodos como first interrompem o loop antecipadamente:
class Squares
include Enumerable
def initialize(limit)
@limit = limit
end
def each
n = 1
while n * n <= @limit
yield n * n
n += 1
end
end
end
p Squares.new(50).to_a
p Squares.new(1000).first(3)
puts Squares.new(100).sumSaída:
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9]
385Quando os elementos definem <=>, os métodos de ordenação de Enumerable, como sort, min e max, funcionam sem um bloco. Caso contrário, eles recebem um, como em sort_by e min_by:
class Team
include Enumerable
def each(&block)
@players.each(&block) # passa o bloco diretamente adiante
end
end
team.sort_by(&:age)
team.min_by(&:score)Desafio
FácilComplete a classe Playlist. Ela contém objetos Song (com title e seconds) adicionados com add, inclui Enumerable e define each, que produz cada música na ordem em que foi adicionada.
O código fornecido adiciona uma música por linha de entrada (title,seconds) e, em seguida, usa apenas métodos de Enumerable na playlist: imprime o número de músicas, os títulos unidos por vírgulas, a duração total no formato m:ss, o título mais longo e os títulos das músicas com mais de 3 minutos, ordenados alfabeticamente (ou none).
Seu código deve ficar em song.rb e playlist.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'song'
require_relative 'playlist'
# Código de entrada/saída fornecido: mantenha-o como está
input = []
while (line = gets)
input << line.chomp
end
list = Playlist.new
input.each do |line|
title, seconds = line.split(",")
list.add(Song.new(title, seconds.to_i))
end
total = list.sum(&:seconds)
long = list.select { |s| s.seconds > 180 }.map(&:title).sort
puts "songs: #{list.count}"
puts "titles: #{list.map(&:title).join(", ")}"
puts format("total: %d:%02d", total / 60, total % 60)
puts "longest: #{list.max_by(&:seconds).title}"
puts "over 3 min: #{long.empty? ? "none" : long.join(", ")}"
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de Livros3Métodos e Variáveis de Classe
Métodos de ClasseVariáveis de Instância da ClasseConstantesMétodos de FábricaRevisão - Códigos de Cupom6Módulos e Mixins
Módulos e includeEstendendo ObjetosO Módulo ComparableO Módulo EnumerableRecapitulação - Liga EsportivaPratique por conta própria: Compilador de Ruby online