If you glanced through the Table of Contents before doing a deep dive into this book, I’ve got 2 things to say to you:

1) I commend your thoroghness

2) You probably thought the “Loops” section should be before Anonymous Functions. Loops are a much simplier concept right?

In PHP and in several of the other major scripted lanuages you’re absolutely correct. However, it was in your best interest to at least get a look at Blocks first. This is because Ruby’s loops accept a block as an argument.

Alright let’s start with PHP’s common sense foreach loop structure:

    $things = ['stars', 'moon', 'cats'];
    
    foreach($things as $thing) {
        echo $thing;
    }
    
    => 'stars'
    => 'moon'
    => 'cats'

Here foreach is it’s own function, it accepts a variable $things and it iterates over each as $thing.

Here’s the same basic loop, but in Ruby:


    things = ['stars', 'moon', 'cats']
    
    things.each do |thing|
      puts thing
    end
    
    => 'stars'
    => 'moon'
    => 'cats'

Where’s the standalone foreach function?!? Sorry, it doesn’t exist here. Instead the Array class has a method that accepts a Block and that Block is passed each String in things.

This is the most confusing part of Ruby that trips up beginners - I know because it did for me when I attempted to learn Ruby as my first language. In order to understand how these loops work, you have to realize the concept of anonymous functions. Strange! But awesome.

This same format applies to all of the common Array operations you’re used to in PHP, like array_map and array_reduce. Here’s an example of a common transformation task with array_reduce in PHP:

    $beers = ['IPA', 'Belgian Trippel', 'Belgian White Ale'];
    
    $loudBeers = array_map(function($beer) {
       return strtoupper($beer); 
    }, $beers);
    
    printr($loudBeers);
    
    => Array (
          0 => "BELGIAN TRIPPEL"
          1 => "BELGIAN_WHITE_ALE"
       )

Again, for Ruby we simply use a method on the Array class:


    loudBeers = beers.map { |beer| beer.upcase }
    
    print loudBeers
    
    => ["BELGIAN TRIPPEL", "BELGIAN WHITE ALE"] => nil

BONUS ROUND

In case you thought the above example couldn’t get any more concise, you’re in for a special treat. The example below does the exact operation as our last one:


    loudBeers = beers.map(&:upcase)
    
    print loudBeers
    => ["BELGIAN TRIPPEL", "BELGIAN WHITE ALE"] => nil

Woah. What the heck is a & and a Symbol doing there?

Answer: you can think of the & immediately to the left of the Symbol as a way to indicate to Ruby that we want that method applied to each item in the Array.

This example performs the same logic as the block example. But as you can see, the Symbol :upcase was just used to tell Ruby to call that method on each of the items. Programming is a game of keystrokes, and here we saved a couple.