Building my first CLI 
Tags: ruby, showdev, beginners, coding
Published: 2021-01-09 08:19:24

##Introduction

About two months ago I started Flatiron's software engineering program. I basically had zero coding skills and knowledge coming into this program. Now that I've been learning Ruby for the past two months, I have built my first CLI. My CLI pulls from a [makeup API](https://makeup-api.herokuapp.com/) to let the user browse specific tags that cater to the users specific needs. After selecting a tag, a list of product types for that tag is given to the user. Selecting a product type will give a detailed list of products with the brand, description, and website link. 

This is my first project so there were some learning curves with github, environments, and coding in general. I came across a lot of useful things while building my CLI that I would like to share.

##system("clear")

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/keh9ltvsmuettxwmrliu.png)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/art3blrjcasph04pwjpt.png)

The best thing for a terminal app is implementing `system("clear")` in your code. I placed this code right after getting the user input, so the terminal window is cleared before the information that the user selected is displayed. This keeps your terminal looking clean and readable for the user after they put inputs into the terminal. Something so little made a huge difference to my CLI.

##Iterators `each`, `map/collect`, `select`
Learning the common iterators and what they return and do is so useful for iterating over collections. I used `.collect` and `.select` to collect information from my API throughout building my CLI.

#####each

`.each` is generally used when you want to do something with each element of an array inside the block. 
```
array = [1, 2, 3, 4, 5]
array.each {|x| puts x}
output => 
1
2
3
4
5
return =>
[1, 2, 3, 4, 5]
```
One thing to note is that `.each` returns the original array object it was invoked upon. If you want to return an array with the results of the method you will have to create a new variable with an empty array and then push the results to that array.
```
array = [1, 2, 3, 4, 5]
new_arr = []
array.each {|x| new_arr << x*2}
new_arr
output => 

return =>
[2, 4, 6, 8, 10]
```

An `.each` iterator I used a lot in my project is `.each_with_index`. This allowed me to iterate over my arrays of information to produce the list menus and the list of products in my CLI. The example below shows `.each_with_index` being used with an array to print a number list for each element of the array. The `x` represents each element of the array and `i` represents the index corresponding to each element. To print a numbered list, we have to add 1 to the index to account for the index starting at 0.

```
array = ["a", "b", "c", "d", "e"]
array.each_with_index {|x, i| puts "#{i + 1}. #{x}"}
output =>
1. a
2. b
3. c
4. d
5. e
return =>
["a", "b", "c", "d", "e"]
```
#####map/collect
The `.collect` or `.map` method allows us to iterate through an array like `.each`, but `.collect` returns a new array with the results of our iterator. `.collect` and `.map` are the same and can be used interchangeably. This iterator was useful in my CLI to iterate over my array of collections to get new arrays with deeper information within the hash of my API. 
```
array = [1, 2, 3, 4, 5]
new_arr = array.collect {|x| x*2}
new_arr
output => 

return =>
[2, 4, 6, 8, 10]
```
#####select
The .select method iterates over an array and grabs all elements for which the specified statement in the block is true. This returns a new array with all the elements that satisfy the block.
```
array = [1, 2, 3, 4, 5]
new_arr = array.select {|x| x.even?}
new_arr
output => 

return =>
[2, 4]
```
#####find
The `.find` method is similar to the `.select` method, but returns the first element that satisfies the block and stops iterating. It does not return an array and does not return all elements that satisfy the block. In the example below, the return is 2, not in an array, and 4 is not returned. 
```
array = [1, 2, 3, 4, 5]
new_arr = array.select {|x| x.even?}
new_arr
output => 

return =>
2
```
##word_wrap gem
For my API, I pull a description for each item, which is a long string. An issue I ran into was the descriptions breaking in the middle of words when the string hit the edge of the terminal. The [word_wrap gem](https://makeup-api.herokuapp.com/) is the gem that fixed this issue. The function of the gem is the name of the gem, it wraps your text to a set width in your terminal.

##In the end...
After finishing my CLI, I realized there were different methods I could've gone about with my CLI. Having people look over my code, I realized I brute forced some parts of my CLI, but I'm still a beginner. I will probably go through it in the future to improve the code, but for now my finished CLI is a finished product and functions perfectly, and I feel accomplished with my first CLI.