Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
README.md
ruby-enumerable-comparable_notes.pdf

README.md

LESSON: ruby-enumerable-comparable


2018-07-05

OBJECTIVES

By the end of this, developers should be able to:

  • Add Comparable operators to a class.
  • Add Enumerable methods to a class.

VOCABULARY

module: a collection of methods encompassed in the Module keyword. Can also be used as a namespace (Math::PI will return the constant PI in the Math module / namespace. Why not put PI in the global namespace?) -

mixin: adding functionality to a class by including a module

NOTES

  • Comparable - module that contains methods that allow two things to be compared
  • used by classes whose objects may be ordered
  • Comparable is a mixin that the Enumerable mixin relies on for several method's implementations.
  • If Enumerable#max, #min, or #sort is used, the objects in the collection must also implement a meaningful <=> operator, as these methods rely on an ordering between members of the collection.
    • to use comparable in your own class, the class must implement the <=> (a.k.a spaceship) method
    • <=> compares one item against another, returning -1 if item is less than, 0 if equal, or 1 if greater than, other item
    • gives class the <, <=, ==, >=, and > and between? methods

Differences between Class and Module:

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ class                     ║ module                          ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated       ║ can *not* be instantiated       ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage         ║ object creation           ║ mixin facility. provide         ║
║               ║                           ║   a namespace.                  ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass    ║ module                    ║ object                          ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods       ║ class methods and         ║ module methods and              ║
║               ║   instance methods        ║   instance methods              ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance   ║ inherits behaviour and can║ No inheritance                  ║
║               ║   be base for inheritance ║                                 ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion     ║ cannot be included        ║ can be included in classes and  ║
║               ║                           ║   modules by using the include  ║
║               ║                           ║   command (includes all         ║
║               ║                           ║   instance methods as instance  ║
║               ║                           ║   methods in a class/module)    ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension     ║ can not extend with       ║ module can extend instance by   ║
║               ║   extend command          ║   using extend command (extends ║
║               ║   (only with inheritance) ║   given instance with singleton ║
║               ║                           ║   methods from module)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

(from this SO answer)

Investigating Comparable module (introspection / ruby meta-programming)

pry(main)> Comparable
=> Comparable
[19] pry(main)> Comparable.class
=> Module
[16] pry(main)> Comparable.class.superclass
=> Object
[17] pry(main)> Comparable.class.superclass.superclass
=> BasicObject
[18] pry(main)> Comparable.class.superclass.superclass.superclass
=> nil
[20] pry(main)> Comparable.is_a? Module
=> true
[21] pry(main)> Comparable.is_a? Class
=> false
[14] pry(main)> Comparable.ancestors
=> [Comparable]
pry(main)> Comparable.included_modules
=> []
[20] pry(main)> Array.included_modules
=> [Enumerable, PP::ObjectMixin, Kernel]
[21] pry(main)> String.included_modules
=> [Comparable, PP::ObjectMixin, Kernel]
[22] pry(main)> Integer.included_modules
=> [Comparable, PP::ObjectMixin, Kernel]

Using Comparable in custom class

(taken from docs)

class SizeMatters
  include Comparable
  attr :str
  def <=>(other)
    str.size <=> other.str.size
  end
  def initialize(str)
    @str = str
  end
  def inspect
    @str
  end
end

s1 = SizeMatters.new("Z")
s2 = SizeMatters.new("YY")
s3 = SizeMatters.new("XXX")
s4 = SizeMatters.new("WWWW")
s5 = SizeMatters.new("VVVVV")

s1 < s2                       #=> true
s4.between?(s1, s3)           #=> false
s4.between?(s3, s5)           #=> true
[ s3, s2, s5, s4, s1 ].sort   #=> [Z, YY, XXX, WWWW, VVVVV]