El módulo Enumerable
Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 30 de 57.
Enumerable es el módulo que está detrás de los métodos de colección de los arrays y los hashes. Una clase que define each, produciendo sus elementos uno por uno, e incluye Enumerable obtiene map, select, count, sort_by, min_by, sum, include? y docenas más:
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")Salida:
INTRO, DUNE, OUTRO
["Intro", "Outro"]
3
trueyield pasa un valor al bloque que la persona que llama proporcionó a each. La clase decide qué es un elemento, por ejemplo, una línea de texto, un par de valores o uno de sus propios 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 }Salida:
["apple", "plum"]
["plum", 7]Los elementos no tienen que almacenarse. each puede calcularlos sobre la marcha, y métodos como first detienen el bucle antes:
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).sumSalida:
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9]
385Cuando los elementos definen <=>, los métodos de ordenación de Enumerable, como sort, min y max, funcionan sin un bloque. De lo contrario, reciben uno, como en sort_by y min_by:
class Team
include Enumerable
def each(&block)
@players.each(&block) # pasa el bloque directamente
end
end
team.sort_by(&:age)
team.min_by(&:score)Desafío
FácilCompleta la clase Playlist. Contiene objetos Song (con title y seconds) añadidos con add, incluye Enumerable y define each, que produce cada canción en el orden en que se añadió.
El código proporcionado añade una canción por cada línea de entrada (title,seconds) y luego usa únicamente métodos de Enumerable en la lista de reproducción: imprime el número de canciones, los títulos unidos por comas, la duración total en m:ss, el título más largo y los títulos de las canciones de más de 3 minutos, ordenados alfabéticamente (o none).
Tu código va en song.rb y playlist.rb. main.rb contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
require_relative 'song'
require_relative 'playlist'
# Código de entrada/salida suministrado: déjalo 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 lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesVariables de instanciaMétodos y selfto_s e inspectRepaso: tarjeta de biblioteca4Encapsulación
Métodos privadosMétodos protegidosAsignadores privadosProtección del estadoRepaso: máquina expendedora7Polimorfismo y tipado pato
PolimorfismoTipado patoMétodos abstractoscase y clasesRepaso: métodos de pago2Accesores y self
Lectores y escritoresSetters personalizadosself en los métodosIdentidad e igualdadRepaso: lista de contactos5Herencia
SubclasesSobrescritura de métodosLlamar a superis_a? y ancestrosRepaso - Nómina del personal8Métodos especiales
Igualdad y hashMétodos de operadoresIndexación y adiciónColecciones personalizadasRepaso: fracciones11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de libros3Métodos y variables de clase
Métodos de claseVariables de instancia de claseConstantesMétodos de fábricaRepaso: códigos de cupón6Módulos y mixins
Módulos e inclusiónExtender objetosEl módulo ComparableEl módulo EnumerableRepaso: liga deportivaPractica por tu cuenta: Compilador de Ruby online