Using TTY::Prompt for your CLI app
Tags: ruby, beginners, bash
Published: 2019-06-04 23:13:47

   I recently became a software engineering student at Flatiron School, a coding school originally based in New York that's branched out across the country. 

   In our third week, we were charged with creating our first robust project: a CLI (Command Lind Interface) app. A project we'd then have to present. In front of all our classmates. It was awful. But, in all seriousness, a CLI app is a great project for beginners and something I highly recommend as a great challenge to step up your learning. 

   And for those who want to take their CLI app to the next level, I present to you an awesome gem that's simple to use and makes your app look a step above without extra fuss:
<br>
#TTY::Prompt 

[TTY::Prompt](https://github.com/piotrmurach/tty-prompt#ttyprompt-), created by [Piotr Murach](https://github.com/piotrmurach), is an open-source gem that provides "a beautiful and powerful interactive command line prompt."*  It's pretty great. If your CLI app ever needs input from a user (which it should because, why not?), this is the gem for you. It gives you great options to display prompts or menus with choices that your user can fill in or pick from and makes the styling neat and handsome. Like so: 
<br>
##How to use it

It's simple! 
1. Add the gem to your app's Gemfile: `gem 'tty-prompt'`
2. Execute it with `bundle`
3. Or install it manually in your bash with `gem install tty-prompt`

When you're using it in your application, all you need is to create a variable `prompt` and create a new instance of the TTY::Prompt class. 
```ruby
prompt = TTY::Prompt.new
```
This way, you can call on any of the methods the gem provides on this new prompt variable. 
```ruby
prompt.ask(‘Your question here')
```
---
<br>
---
---
##Methods

There are a few basic Prompt methods you're most likely to use in your CLI app:
- [`.ask`](https://github.com/piotrmurach/tty-prompt#21-ask)
- [`.yes?`](https://github.com/piotrmurach/tty-prompt#25-yesno)
- [`.mask`](https://github.com/piotrmurach/tty-prompt#24-mask)
- [`.select`](https://github.com/piotrmurach/tty-prompt#262-select)

---

####ask
To ask a question that the user would respond with simple input, use the `ask` method. As with any time you want to use TTY::Prompt, you first need to create a prompt, then call the method on that prompt variable you have created. 
```ruby
prompt = TTY::Prompt.new
prompt.ask('What is your name?') 
# => What is your name? doge
# => "doge"
```
The return value is a string of your user's input. So say your user types in "doge," when they hit the return key, not only will your return value be equal to "doge," but your user also probably looks something like this: ![doge dog](https://www.tynker.com/projects/images/58338362157d72a65c8b456a/doge---doge.png)

---

####yes?/no?
The [`yes?`] method is similarly built, but will only return true or false when the user presses 'y' or 'n' respectively. 
```ruby
prompt.yes?(‘Are you a dog?’)
#=> Are you a dog? yes
#=> true
```
You can also change the defaulted (Y/n) option to say something like (Agree/Disagree) instead, with the `.suffix` option.

[`yes?`]:https://github.com/piotrmurach/tty-prompt#25-yesno
---

####mask
A nifty tool for when you require confidential information from your user, like a password, is using the [`mask`] method. 
```ruby
prompt.mask(‘Enter your password:')
#=> Enter your password: ••••
```

[`mask`]:https://github.com/piotrmurach/tty-prompt#24-mask
---

###Menu methods
Prompt gives you a few different ways to create menus where your user selects one or more from a list of options to choose from. The most basic way to create a menu would be with a `select` method.



####select
Whenever you need your user to choose one of a list of options, the [`select`] method is your friend. Your user will use the up/down keys to choose from a list of options you provide, which will then return a string of the option chosen: 
```ruby
prompt.select("What's your favorite kind of taco shell?", %w(Soft_taco Hard_taco 
Porque_no_los_dos?))
```
```
#What's your favorite kind of taco shell? 
#  Soft_taco
#  Hard_taco
#‣ Porque_no_los_dos?
#=> "Porque_no_los_dos?"
```
![porque no los dos girl](https://i.imgur.com/s4eamxv.jpg?fb)

There are two other variations on the select method:
1. [`multi_select`] allows the user to select more than one option:

2. [`enum_select`] allows users to select an option by entering the numbered key corresponding to its option:
```ruby
      prompt.multi_select("What's your favorite pet?", %w(cats dogs fish 
      birds reptiles plants))

      #What's your favorite pet? cats, dogs, plants
      #  ⬢ cats
      #  ⬢ dogs
      #  ⬡ fish
      #  ⬡ birds
      #  ⬡ reptiles
      #‣ ⬢ plants
```      
```ruby
      prompt.enum_select("What's your favorite pet?", %w(cats 
      dogs fish birds reptiles plants))

      #What's your favorite pet? 
      #  1) cats
      #  2) dogs
      #  3) fish
      #  4) birds
      #  5) reptiles
      #  6) plants
      #  Choose 1-6 [1]: 2
```
[`select`]:https://github.com/piotrmurach/tty-prompt#262-select
[`multi_select`]:https://github.com/piotrmurach/tty-prompt#263-multi_select
[`enum_select`]:https://github.com/piotrmurach/tty-prompt#264-enum_select
---
<br>
---
---
##Cool Features
TTY::Prompt gives you a lot of ways to personalize your prompts. Let's go over some of the more useful ones. 

---

####Default
Many of the methods have the option of defining a default value to your prompts. It's a neat feature to have when options are given in cases of exceptions to the norm. Or maybe you foresee users being particularly lazy or paranoid about using their name; you can have a `default:` value set to "Anonymous". 
```ruby
prompt.ask(‘What's your name?', default: 'Anonymous')
# =>
# What is your name? (Anonymous)
```

TTY::Prompt is smart enough to have the default option available for quite a few methods:
- **`ask`**
```ruby
prompt.ask(‘What industry do you work in?', default: ’Tech')
# =>
# What industry do you work in? (Tech)
```
- **`yes?`**
```ruby
prompt.yes?(‘Is GrumpyCat grumpy?', default: true)
#=> Is GrumpyCat grumpy? yes
#=> true
```
![grumpy cat](https://static.toiimg.com/thumb/imgsize-533580,msid-69374262,width-400,resizemode-4/69374262.jpg)

- **And any menu method** with `menu.default <default value(s)>` inside the menu iteration
```ruby
prompt.select('Choose your fruit of choice') do |menu|
  menu.default 3

  menu.choice 'Papaya', 1
  menu.choice 'Mango', 2
  menu.choice 'Watermelon', 3
end
```
```ruby
prompt.multi_select("Select tea?") do |menu|
  menu.default 2, 5

  menu.choice :green
  menu.choice :black
  menu.choice :white
  menu.choice :earl_grey
  menu.choice :sweet
end
```
---

####Require

The `:require` option allows a prompt to be (you guessed it) required before a user can move on. Like `default:`, it can be added to essentially any prompt method, which makes them both extremely useful features. 

```ruby
prompt.mask('Enter a password:', required: true)
#Enter a password: 
#>> Value must be provided
```

```ruby
prompt.ask('What is your name?', required: true)
#What is your name? 
#>> Value must be provided
```

Admittedly, with methods like the menu methods, the user would have to input a response before they can move on regardless of whether or not it is required, so pinning it onto the end of a menu prompt would be redundant. 

---
####Return values

Return values are defaulted to be a string of whichever option the user chooses, like in the first doge example. But return values can also be customized by adding the return value you'd like for that choice right after choice itself like you see in the fruit example above: `menu.choice 'Papaya', 1`   

---
<br>
---
---
Though I've claimed these methods here to be the most useful, there are many more features available with TTY::Prompt and I encourage you to fully explore their [documentation page](https://github.com/piotrmurach/tty-prompt#ttyprompt-) and give yourself a chance to play around with them. Happy Coding!

---

 *- Edited June 21st to credit the creator.