Colecciones personalizadas
Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 40 de 57.
Una clase de colección combina varios métodos especiales: each con Enumerable, << para añadir elementos, size, y to_s e inspect para imprimir. each también debería funcionar sin un bloque, devolviendo un enumerador con to_enum, como hacen los arrays:
class TodoList
include Enumerable
def initialize
@items = []
end
def <<(item)
@items << item
self
end
def each
return to_enum(:each) unless block_given?
@items.each { |item| yield item }
self
end
end
list = TodoList.new << "wash" << "shop" << "cook"
list.each.with_index(1) { |item, n| puts "#{n}. #{item}" }
p list.select { |i| i.include?("o") }Salida:
1. wash
2. shop
3. cook
["shop", "cook"]block_given? indica si quien realiza la llamada proporcionó un bloque. El enumerador devuelto sin uno admite encadenamientos como each.with_index, each_slice o next:
class Countdown
include Enumerable
def initialize(from)
@from = from
end
def each
return to_enum(:each) unless block_given?
@from.downto(1) { |n| yield n }
end
end
e = Countdown.new(3).each
puts e.next
puts e.next
p Countdown.new(5).each_slice(2).to_aSalida:
3
2
[[5, 4], [3, 2], [1]]to_s es el texto amigable para los usuarios y inspect un breve resumen para los programadores. Para una colección, inspect normalmente muestra la clase y el tamaño en lugar de cada elemento:
class TodoList
include Enumerable
def initialize(*items)
@items = items
end
def each(&block)
@items.each(&block)
end
def size
@items.size
end
def to_s
map.with_index(1) { |item, n| "#{n}. #{item}" }.join("\n")
end
def inspect
"#<TodoList #{size} items>"
end
end
list = TodoList.new("wash", "shop")
puts list
p listSalida:
1. wash
2. shop
#<TodoList 2 elementos>Enumerable proporciona count, pero no size, empty?, << ni []: esos pertenecen a la clase, porque solo ella sabe cómo se almacenan los elementos. Definirlos hace que la colección parezca un array para quienes la utilizan:
def size
@items.size
end
def empty?
@items.empty?
end
def [](index)
@items[index]
endDesafío
FácilCompleta la clase TodoList. << añade el texto de una tarea y devuelve la lista. each produce las tareas y devuelve to_enum(:each) cuando no se proporciona un bloque. Incluye Enumerable. size devuelve el número de tareas. to_s devuelve las tareas como líneas numeradas, 1. wash, o nothing to do, y inspect devuelve #<TodoList 3 items>.
El código proporcionado añade cada línea de entrada encadenando <<, después imprime la lista, aplica p a la lista, las tareas numeradas con ! mediante each.with_index(1) como 1! wash, el número de tareas que contienen o y la primera tarea en orden alfabético.
Tu código va en todo_list.rb. main.rb contiene el código de entrada/salida proporcionado y no se puede editar.
Pruébalo tú mismo
require_relative 'todo_list'
# Código de entrada/salida suministrado: mantenlo tal como está
input = []
while (line = gets)
input << line.chomp
end
list = input.reduce(TodoList.new) { |l, task| l << task }
puts list
p list
list.each.with_index(1) { |task, n| puts "#{n}! #{task}" }
puts "with o: #{list.count { |t| t.include?("o") }}"
puts "first: #{list.min}"
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 librosPractica por tu cuenta: Compilador de Ruby online