TTY::Prompt 101
If you are new to Ruby, one of your first non-array/hash projects may involve a Command Line Interface (CLI). A CLI allows the user to respond to its operating system by typing in lines of text. The CLI then takes in those commands from the user and starts what is essentially a conversation as the operating system that implements the CLI can go back and forth with the user to send and receive information. Luckily, a kind instructor introduced me to TTY::Prompt to help me create my first CLI terminal app.
The ‘TT’ stands for teletype, which was a typewriting machine that was capable of communicating messages from one place to another via electric communications. Much like those who encountered the teletype when it first circulated in the 1920’s, I felt my capabilities expand upon installing the TTY::Prompt gem. This article will be a guide for a first-time TTY:Prompt programmer. We will go over the basics involving prompt.ask, prompt.yes?, prompt.select, and prompt.multi_select, while hashing over a couple of tricks I encountered to help make your usage more user friendly. You can also read their website, on which many of the capabilities are easy to understand.
First, let’s get your system started with TTY::Prompt. As of May 29th, 2020, you can install the necessary gem files by running in your Terminal:
gem install tty
gem install tty-prompt
At the top of whatever file is using TTY::Prompt, add:
require “tty-prompt”
The last thing you need to do is create an instance of the TTY::Prompt class so you can run your functions.
prompt = TTY::Prompt.new
As long as you place this prompt variable, which, again, is an instance of the TTY::Prompt class, before you wind up calling prompt.ask, prompt.yes?, etc., you are good to go (just remember that, if you are using it inside of a method, you should place prompt = TTY::Prompt.new inside the method and before you run prompt.ask, prompt.yes?, etc.
Great, let’s start with one of the easier ones, prompt.yes?

Prompt.yes? is asking a simple yes or no question. The user can type, “yes”, “no”, or even “y” or “n”. If the user doesn’t type anything before hitting Enter, confirm_selections will assume that the user is saying “yes.” The user’s response to confirm_selections will return true (if “yes”) or nil (if “no”).
Next up is prompt.ask

prompt.ask is asking for the user to respond by typing his or her commands into the Terminal, then hitting Enter. If the user hits Enter without typing in anything, prompt.ask will move on to the next function having received a string value of nil or, more specifically, “”. If you would like to make sure that the user enters something before moving on, you can add an if/else statement to your code.

book_requests will continue to run until its return value, book_list, no longer equals nil.
If you want to fully utilize the TTY::Prompt gem options, you can use the :require option.

Great, now let’s discuss my two favorite TTY::Prompt functions, prompt.select and prompt.multi_select. Both functions send the user a list of options, followed by available choices.

TTY::Prompt tells the user to use ↑/↓ to scroll, then press Enter to select his or her choice. But be aware that these directions will disappear as soon as the user begins scrolling up and down.
Overall, calling on prompt.select (or prompt.multi_select) is preferable to having the user type - and potentially misspell - his or her entry.
The only difference between prompt.select and prompt.multi_select is that, in prompt.multi_select, the user will have the option to pick as many items off the list as he or she chooses. While the image above shows the array of book titles that the user will see for his or her selection, the image below is presenting the same list in a different fashion by using the choices method for more than one choice.

TTY::Prompt tells the user to use ↑/↓ to scroll, then the space bar to select (or deselect) your choices, then Enter to finish. Again, be aware that these directions will disappear as soon as the user begins scrolling up and down.
Let’s say you want to remove a book from your collection.

Your method will ask the user which book or books that they would like to remove. The books that the user selects will be stored in the variable books_to_remove. books_to_remove will then run through the each Enumerable to delete each book to be removed from the book_array_of_titles. The method above then returns the resulting book_array_of_titles.
As a default, whatever option the user chooses in prompt.select and prompt.multi_select (i.e. “Ender’s Game”) will also be its return value(s). However, return values can also be customized by placing the value that your function will instead return after menu.choices “string”,

Also, if your function is taking in an argument that you cannot predict, you can create a hash that will set up the menu.choices correctly with what the user will see and what the function will return.
