Ruby Puts vs Print vs P vs PP vs... Awesome?
Tags: ruby, beginners
Published: 2019-09-09 17:58:44

When it's time to print something to the command line in Ruby, a developer has multiple options. While this can be useful, it can also be a bit confusing. Let's take a look at our options and see if we can clear up some of the confusion.

The five print methods in Ruby that we'll discuss are:

  - puts
  - print
  - p
  - pp
  - ap

For each of these methods, we'll go over how each prints to the command line and most importantly what they return. Knowing this is important, because not understand what a method returns can lead to a lot of bugs in your code, and ultimately, a lot of frustration.

##**Puts**
Puts is the method that you'll find yourself using most often, so let's start there. 

```ruby
// ♥ irb
2.6.1 :001 > puts "Hello World!"
Hello World!
 => nil 
```

As we can see in Interactive Ruby Shell above, the puts method prints whatever you pass it to the command line followed by a newline character. 

Puts will also print the individual elements of an array with the a newline character after each.

```ruby
2.6.1 :001 > puts [1, 2, 3]
1
2
3
 => nil 
```

Puts also turns whatever you pass it into a string using the .to_s method. This causes any nil elements you may have in an array to be printed as an empty string.

```ruby
2.6.1 :002 > puts [1, nil, nil, 4, 5]
1


4
5
 => nil 
```

We also see that puts returns nil. This is important because Ruby uses implicit returns so if you use a puts at the end of a method and you expect it to print the argument and return it, you'll be disappointed. 

Let's take a look an example of this.

```ruby
2.6.1 :002 > def test_of_puts (string)
2.6.1 :003?>   puts string
2.6.1 :004?>   end
 => :test_of_puts 
2.6.1 :005 > return_value = test_of_puts ("Did I get returned?")
Did I get returned?
 => nil 
2.6.1 :006 > return_value
 => nil 
```

![Alt Text](https://media.giphy.com/media/bThzyz6mPU52MK9qgQ/giphy.gif)

##**Print**
Next, let's take a look at print. Print is very similar to puts but there are a few differences. First of all, print also converts the argument you pass it into a string using .to_s and prints it to the command line. But it does not add a newline character.

```ruby
2.6.1 :006 > def print_example
2.6.1 :007?>   print 123
2.6.1 :008?>   print 456
2.6.1 :009?>   end
 => :print_example 
2.6.1 :010 > print_example
123456 => nil 
```
Another way that print differs from puts is that if you pass print an array, it will simply print out the array including the brackets.

```ruby
2.6.1 :011 > print [1, 2, 3]
[1, 2, 3] => nil 
```

As we see in this example, print also returns nil. Sorry Gary Oldman.

![Alt Text](https://media.giphy.com/media/lr5FCH1QDHrhu/giphy.gif)

Good call, Gary! Let's move on to the methods that don't return nil!

##**P**
When we compare the p method to puts and print, we find some major differences. First of all, p prints the the raw object that you pass to it. This is because it uses .inspect to convert the object to a string rather than .to_s. 

```ruby
2.6.1 :001 > puts "Hello World!"
Hello World!
 => nil 
2.6.1 :002 > print "Hello World!"
Hello World! => nil 
2.6.1 :003 > p "Hello World!"
"Hello World!"
 => "Hello World!" 
2.6.1 :004 > p [1, 2, 3]
[1, 2, 3]
 => [1, 2, 3] 
2.6.1 :005 > p hash = {key1: "val1", key2: "val2", key3: "val3"}
{:key1=>"val1", :key2=>"val2", :key3=>"val3"}
 => {:key1=>"val1", :key2=>"val2", :key3=>"val3"} 
```
From this example, we can see that like puts, p adds a newline character to the end of the object that it prints. But p does not return nil. It returns that same object that was passed to it as an argument. This, combine the fact that p prints the raw object to the command line, makes p very useful when debugging.

##**PP**
PrettyPrint, or pp, is a special version of p that is essential exactly the same except for the fact that it attempts to print large hashes and arrays to the command line in a more readable format.

```ruby
2.6.1 :019 > pp ({ key1: 5, key2: { key21: 'val21', key22: 'val22', key23: 'val23' }, key3: { key31: 'val31', key32: 'val32', key33: 'val33' }, key4: [1, 2, 3, 4, 5] })
{:key1=>5,
 :key2=>{:key21=>"val21", :key22=>"val22", :key23=>"val23"},
 :key3=>{:key31=>"val31", :key32=>"val32", :key33=>"val33"},
 :key4=>[1, 2, 3, 4, 5]}
 => {:key1=>5, :key2=>{:key21=>"val21", :key22=>"val22", :key23=>"val23"}, :key3=>{:key31=>"val31", :key32=>"val32", :key33=>"val33"}, :key4=>[1, 2, 3, 4, 5]} 
```
![Alt Text](https://media.giphy.com/media/cHd3jtBy4SVNK/giphy.gif)

Well if you like pp, Gary, you're gonna love ap.

##**AP**
Awesome_print, or ap, was created by Michael Dvorkin and though it is not included in the most recent version of Ruby, the gem can be install by entering the following into a terminal:
```
$ gem install awesome_print
```

Awesome_print one ups pp on a grand scale. Not only does it display nested hashes in a more readable format, but it also prints the index value next to each element of arrays. 
```ruby
2.6.1 :021 > ap ({ key1: 5, key2: { key21: 'val21', key22: 'val22', key23: 'val23' }, key3: { key31: 'val31', key32: 'val32', key33: 'val33' }, key4: [1, 2, 3, 4, 5] })
{
    :key1 => 5,
    :key2 => {
        :key21 => "val21",
        :key22 => "val22",
        :key23 => "val23"
    },
    :key3 => {
        :key31 => "val31",
        :key32 => "val32",
        :key33 => "val33"
    },
    :key4 => [
        [0] 1,
        [1] 2,
        [2] 3,
        [3] 4,
        [4] 5
    ]
}
 => nil 
```


<img src="https://media.giphy.com/media/t9X2fFy8QOT1S/giphy.gif" width=500>
I know, right?!?! Awesome_print brings me to tears too, Gary!

There's just one problem...ap returns nil.

<img src="https://media.giphy.com/media/L48kNVDnZaH60/giphy.gif" width="500">
I know Gary. I know. Life's like that sometimes. We don't always get everything we want. But now that we have a better understanding of how these five Ruby print methods work, we'll be better able to use the right tool for the right job.

###**References**

####Ruby Kernel verson: 2.6.1
  https://ruby-doc.org/core-2.6.1/Kernel.html#method-i-puts

####Awesome_print
  Author: Michael Dvorkin
  https://github.com/awesome-print/awesome_print/
  http://www.dvorkin.net

####GIPHY
Each gif in the order they appear.
https://giphy.com/gifs/reaction-bThzyz6mPU52MK9qgQ
https://giphy.com/gifs/reaction-done-gary-oldman-lr5FCH1QDHrhu
https://giphy.com/gifs/reaction-wink-gary-oldman-cHd3jtBy4SVNK
https://giphy.com/gifs/reaction-gary-oldman-fifth-element-t9X2fFy8QOT1S
https://giphy.com/gifs/the-fifth-element-gary-oldman-L48kNVDnZaH60