Creating My CLI

At first, building my CLI program with Ruby was a daunting task. Here are some helpful tips I learned along the way:

Cody Merritt
2 min readDec 13, 2020

Make It Your Own

Right out the gate, navigating the nested structure of my gem-in-progress was the first hurdle. It can be difficult for me at times to understand the relationships between files, executables, and the requirements all of them may need. I found that letting Bundler automatically organize my gem didn’t help me to understand those complex connections, so I encourage someone struggling with that concept to create the filing themselves!

guide for gem directory structuring

.gitignore Is Your Friend

A gitignore file tells Git to exclude certain files from being tracked for publishing to your remote repository. For me, this was helpful because I like to include Markdown files like a page for taking notes, organize my structuring, and drafting the accompanying blog post inside my project directory without having to constantly add, commit and push their changes whenever I edit them. That way, I had quick access to my thoughts and some resources related to the project without them being public on Github.

gitignore Documentation

Screen.clear

An easy but impactful way to cleanly execute your gem is to include this module at the top of your CLI class file:

module Screen   def self.clear      print “\e[2J\e[f”   endend

After that, make sure you include this line of code inside your CLI class:

extend Screen

With that, anytime you write `Screen.clear` in your code, your terminal will clear the screen and execute the next line of code at the top. I found this great for keeping the line of sight consistent for the user.

The Order of Truth Matters

One of my first stuck moments was delivering a single source of truth under my API class. For Quotebook, every Quote has an author and a topic keyword associated to it.

def collect_quotes   PATHS.each do |path|      url = BASE_URL + path      uri = URI(url)      response = Net::HTTP.get(uri)      formatted_resp = JSON.parse(response)      formatted_resp[“data”].each do |quote_hash|         genre = Genre.new(quote_hash[“quoteGenre”])         author = Author.new(quote_hash[“quoteAuthor”])         Quote.new(quote_hash[“quoteText”], author, genre)      end   endend

I had an “Ah Ha!” moment after I was originally instantiating my Quote class inside the iteration over my different full URL paths before instantiating my Genre and Author classes. This was leading to three different classes having no relationship amongst themselves, hence no single source of truth.

--

--