Skip to content

Instantly share code, notes, and snippets.

@MilanGrubnic70
Last active August 29, 2015 14:00
Show Gist options
  • Save MilanGrubnic70/11100031 to your computer and use it in GitHub Desktop.
Save MilanGrubnic70/11100031 to your computer and use it in GitHub Desktop.
Modules & Mixins

#Modules & Mixins ####CapitalizedCamelCase

You can think of a module as a toolbox that contains a set methods and constants. We keep a bunch of them in modules and only pull in those module toolboxes when we need the constants and methods inside!

You can think of modules as being very much like classes, only modules can't create instances and can't have subclasses. They're just used to store things!

module Circle

  PI = 3.141592653589793
  
  def Circle.area(radius)
    PI * radius**2
  end
  
  def Circle.circumference(radius)
    2 * PI * radius
  end
end

One of the main purposes of modules is to separate methods and constants into named spaces. This is called (conveniently enough) namespacing, and it's how Ruby doesn't confuse Math::PI and Circle::PI.

See that double colon we just used? That's called the scope resolution operator, which is a fancy way of saying it tells Ruby where you're looking for a specific bit of code. If we say Math::PI, Ruby knows to look inside the Math module to get that PI, not any other PI (such as the one we created in Circle).

require 'module'

Some modules, like Math, are already present in the interpreter. Others need to be explicitly brought in, however, and we can do this using require.

include module

Any class that includes a certain module can use those module's methods! A nice effect of this is that you no longer have to prepend your constants and methods with the module name. Since everything has been pulled in, you can simply write PI instead of Math::PI.

module Action
  def jump
    @distance = rand(4) + 2
    puts "I jumped forward #{@distance} feet!"
  end
end

class Rabbit
  include Action
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

class Cricket
  include Action
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

peter = Rabbit.new("Peter")
jiminy = Cricket.new("Jiminy")

peter.jump
jiminy.jump

Mixin - When a module is used to mix additional behavior and information into a class, it's called a mixin. Mixins allow us to customize a class without having to rewrite code!

# ThePresent has a .now method that we'll extend to TheHereAnd

module ThePresent
  def now
    puts "It's #{Time.new.hour > 12 ? Time.new.hour - 12 : Time.new.hour}:#{Time.new.min} #{Time.new.hour > 12 ? 'PM' : 'AM'} (GMT)."
  end
end

class TheHereAnd
  extend ThePresent
end

TheHereAnd.now

Extend - The extend keyword mixes a module's methods at the class level. This means that class itself can use the methods, as opposed to instances of the class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment