Ruby Oo Macros Readme

Objectives

  1. Learn the definition of a macro.
  2. See how macros can abstract away the explicitly defined setter and getter methods in a Ruby class.

What is a Macro?

Normally when you write a method you are manipulating and returning some kind of data. This (kind of useless) method takes an integer and returns an integer:

def plus_three(num)
  num + 3
end

Ruby's #map method is called on an enumerable and returns an array:

mantra = ["Don't", "Repeat", "Yourself"]

mantra.map do |word|
  word[0]
end

# => ["D", "R", "Y"] 

In Ruby a macro is like a method, just some code, that instead of returning a Ruby datatype returns more Ruby code! This code will get executed along with all the other code you have written when you run your program. In this lab we will be using a macro, again think of this as a method, to write the definitions of other methods, crazy!

The implementation of macros is considered metaprogramming––the writing of programs that operate on other programs. Metaprogramming is a powerful tool. It can make our lives easier by automating repetitive tasks or providing something like a mini-language inside of another programming language that has the benefits of being concise and descriptive.

If this sounds complicated, the answer is it can be—though it doesn't need to be. A danger of metaprogramming is that it can result in very hard to follow code that obscures what is actually happening.

Below we'll implement macros to abstract away the manual, explicit definition of setter and getter methods in a Ruby class.

Attribute Readers, Writers and Accessors

In object-oriented Ruby, there is a strong convention to have a setter and a getter method that pertain to the same attribute. For example, a .name getter and a .name= setter on our Person class. Because this pattern is so common, we find ourselves making these manual setter and getter definitions again and again. As Rubyists, we are lazy, and this is a virtue. If we can achieve the same result with less code, we'll do it.

Check out the example below:

class Person

  attr_reader :name
  attr_writer :name

end

The attr_reader macro, followed by the attribute name :name, created a getter method for us.

The attr_writer macro, followed by the attribute name :name, created a setter method for us.

We can now do the following, without explicitly defining a .name or .name= method ourselves:

jay_z = Person.new
jay_z.name = "Shawn Carter"
jay_z.name
  => "Shawn Carter"

Let's compare a Person class that uses macros to one that uses explicit setter and getter methods:

Macros

class Person
  attr_writer :name
  attr_reader :name

end

Explicit Method Definitions

class Person

  def name=(name)
    @name = name
  end

  def name
    @name
  end
end

Attribute Accessors

If we know that we are going to be reading and writing to the name attribute on our Person class, we can use another macro called an attribute accessor.

So this code...

class Person
  attr_writer :name
  attr_reader :name

end

...can now be written like this:

class Person
  attr_accessor :name

end

We now have access to reader and writer methods from one macro!

Using Macros is Usually Better

The usage of macros is preferred over the explicit definition of setter and getter methods, unless you need to customize the implementation of a method, like in our previous lesson when we defined .name as returning the first and last name variables combined.

To understand why, simply look at the code above. Which class would you rather write? The longer one, or the shorter one?

When opening up a class, attr_accessor and friends allow you to get a high level overview of the class right from the start.

As developers we spend more time reading rather than writing code, so it's important that the code we write be clear, concise and eloquent. We want to be kind to our future selves (when we come back to the programs we've written) and to other developers who will work with our code.

Resources

View Object Accessors on Learn.co and start learning to code for free.

View Object Accessors on Learn.co and start learning to code for free.

Unlock your future in tech
Learn to code.

Learn about Flatiron School's Mission

With a new take on education that falls somewhere between self-taught prodigy and four-year computer science degree, the Flatiron School promises to turn students with little programming experience into developers.

In the six months since the Manhattan coding school was acquired by WeWork, it has spawned locations in Washington, D.C., Brooklyn, and London. Now, WeWork is opening a fourth Flatiron School location, this time in Houston.

Adam Enbar, Flatiron School's cofounder, believes now is the time to grow. "How the world is changing has impacted working and learning in very similar ways. We think education fundamentally is about one thing: enabling people to pursue a better life."

Learn. Love. Code.
Students come to Flatiron School to change their lives. Join our driven community of career-changers and master the skills you need to become a software engineer or a data scientist.
Find Us