0Pricing
Ruby Academy · Lesson

Comparable and Enumerable

Standard mixins.

Comparable and Enumerable is a free Ruby Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Ruby Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Standard Mixins

Ruby ships powerful modules you can mix into your own classes. Two stars are Comparable and Enumerable. Each gives you many methods in exchange for implementing just one.

puts Comparable.instance_methods.sort.inspect

Comparable Needs <=>

Comparable requires you to define the spaceship operator <=>, which returns -1, 0, or 1. In return you get <, <=, ==, >, >=, and between?.

class Weight
  include Comparable
  attr_reader :grams
  def initialize(g); @grams = g; end
  def <=>(other); grams <=> other.grams; end
end
puts Weight.new(50) < Weight.new(80)

Free Comparison Methods

With one operator defined, all the comparison methods just work.

class Weight
  include Comparable
  attr_reader :grams
  def initialize(g); @grams = g; end
  def <=>(other); grams <=> other.grams; end
end
a = Weight.new(100)
b = Weight.new(100)
puts a == b
puts Weight.new(30).between?(Weight.new(10), Weight.new(50))

clamp from Comparable

Comparable also gives clamp, which keeps a value within a range.

puts 15.clamp(0, 10)
puts (-5).clamp(0, 10)
puts 7.clamp(0, 10)

Sorting Comparable Objects

Because <=> is defined, an array of your objects can be sorted automatically.

class Weight
  include Comparable
  attr_reader :grams
  def initialize(g); @grams = g; end
  def <=>(other); grams <=> other.grams; end
  def to_s; "#{grams}g"; end
end
list = [Weight.new(30), Weight.new(10), Weight.new(20)]
puts list.sort.map(&:to_s).inspect

Enumerable Needs each

Enumerable requires you to define each. In return you get map, select, reduce, min, max, sort, and dozens more.

class TodoList
  include Enumerable
  def initialize(*items); @items = items; end
  def each(&block); @items.each(&block); end
end
list = TodoList.new("buy milk", "call mom")
puts list.map(&:upcase).inspect

Aggregation for Free

With each in place, aggregate methods like count, min, and include? are available.

class Scores
  include Enumerable
  def initialize(*n); @n = n; end
  def each(&block); @n.each(&block); end
end
s = Scores.new(8, 3, 9, 4)
puts s.max
puts s.min
puts s.count

select and reject

Filtering methods come along too.

class Numbers
  include Enumerable
  def initialize(*n); @n = n; end
  def each(&block); @n.each(&block); end
end
nums = Numbers.new(1, 2, 3, 4, 5, 6)
p nums.select(&:even?)
p nums.reject(&:even?)

reduce for Totals

reduce (alias inject) combines elements, e.g. summing them.

class Basket
  include Enumerable
  def initialize(*p); @p = p; end
  def each(&block); @p.each(&block); end
end
b = Basket.new(10, 20, 30)
puts b.reduce(0) { |sum, price| sum + price }

Combine Both Mixins

Add Comparable for sorting plus Enumerable for iteration and your class feels like a built-in collection.

class Playlist
  include Enumerable
  def initialize(*songs); @songs = songs; end
  def each(&block); @songs.each(&block); end
end
pl = Playlist.new("c", "a", "b")
puts pl.sort.inspect
puts pl.first

Putting It Together

Standard mixins reward a tiny contract:

  • Comparable: define <=>, get all comparisons.
  • Enumerable: define each, get the whole collection toolkit.
class Bag
  include Enumerable
  def initialize(*x); @x = x; end
  def each(&b); @x.each(&b); end
end
puts Bag.new(3, 1, 2).sort.inspect

Quick Check

Test your understanding of standard mixins.

Recap

You learned standard mixins:

  • Comparable needs <=> and gives comparison + clamp + between?.
  • Enumerable needs each and gives map/select/reduce/min/max and more.
  • Together they make custom classes feel native.
class Temp
  include Comparable
  attr_reader :deg
  def initialize(d); @deg = d; end
  def <=>(o); deg <=> o.deg; end
end
puts Temp.new(20) > Temp.new(15)

Frequently asked questions

Is the “Comparable and Enumerable” lesson free?

Yes — the full text of “Comparable and Enumerable” is free to read here on the web, and the Ruby Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Ruby Academy course, upgrade to CoddyKit PRO.

What will I learn in “Comparable and Enumerable”?

Standard mixins. You practise Ruby Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Ruby Academy?

No prior experience is required. Ruby Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Comparable and Enumerable” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Ruby Academy lesson?

Yes. Every Ruby Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Defining Modules
  2. include and extend
  3. Comparable and Enumerable
  4. prepend and Method Resolution
← Back to Ruby Academy