More than 1 Type of Anonymous Function

For all it’s simplicity, sometimes Ruby complicates things a bit.

Ruby has 3 structures for the anonymous functions concept. Let’s break them down into laymen’s terms and demystify with examples:

Block - an anonymous function that’s passed to a method. It cannot be stored into a variable or executed by itself


    # Execute a given block _before_ Taylor Swift's Award Ceremony
    def interrupt(block)
      yield
      puts '<Taylor Swift\'s award ceremony>'
    end
    
    interrupt do
       puts 'Imma let you finish but Beyonce had the best...' 
    end
    
    => 'Imma let you finish but Beyonce had the best...'
    => '<Taylor Swift\'s award ceremony>'

Ok, this is going to look really funky at first. But try replacing the Ruby specific keyword block with an anonymous function and replace yield with our regular PHP syntax. You’ll see it’s actually very similar to PHP once it’s broken down:

    // Execute a given anonymous function _before_ Taylor Swift's Award Ceremony
    def interrupt($block) {
        $block();
        echo '<Taylor Swift\'s award ceremony>';
    }
    
    interrupt(function() {
        echo 'Imma let you finish but Beyonce had the best...'
    });
    
    => 'Imma let you finish but Beyonce had the best...'
    => '<Taylor Swift\'s award ceremony>'

Proc - a Ruby anonymous function that is actually an object and can be stored in a variable or executed immediately:


    anonymous_function = Proc.new { puts 'I\'m a strong, independent function who don\'t need no wrapper Class to get stuff done.' }
    
    anonymous_function.call
    
    => 'I\'m a strong, independent function who don\'t need no wrapper Class to get stuff done.'

And that’s really the big difference between Procs and Blocks. Blocks can’t live on their own outside of a method, but Procs can.

Just for fun, here’s the same idea in PHP:

    $anonymous_function = (function() {
        echo 'I\'m a strong, independent function who don\'t need no wrapper Class to get stuff done.'
    });
    
    $anonymous_function();
    
    => 'I\'m a strong, independent function who don\'t need no wrapper Class to get stuff done.'

Since you don’t execute methods with with paranthesis in Ruby, they have a reserved method name for Closures called call that is the designated ().

Lamda - A Ruby anonymous function that’s basically a Proc, but with 2 very minor twists:

1) Lambdas actually check for the number of arguments expected, whereas Procs don’t really care


    doesnt_care = Proc.new { |something| puts something }
    
    # notice that we didn't give `call` any argument what-so-ever here
    # but it still chugs along and doesn't throw an Exception
    doesnt_care.call 
    
    => nil

A Lambda is like the one friend who’s taking their Jimmy John’s sandwich back because they asked for pickles but didn’t get any:


    does_absolutely_care = Proc.new { |something| puts something }
    
    # Again, no arguments but Lambdas care A LOT.
    does_absolutely_care.call
    
    => ArgumentError: wrong number of arguments (0 for 1)

2) Lambdas can actually return inside of themselves whereas Procs only return outside of themselves

What? I know I know, it’s confusing wording. However it’s actually not that complicated at all. returning inside of a PHP or Javascript function normally ends the function and returns the result. In Ruby, Lamdas exact exactly like that:


    def journey
      puts 'Oh oh, we\'re halfway there'
        
      next_lyric = Lambda.new do 
          puts 'We\'re living on a prayer!' 
          return # <- Notice this little `return` right here. Very important.
      end
      next_lyric.call
        
      puts 'Take my hand, we\'ll make it swear!'
    end
    
    journey
    
    => 'Oh oh, we\'re halfway there'
    => 'We\'re living on a prayer!'
    => 'Take my hand, we\'ll make it swear!'

In our example, after our little Lambda named next_lyric finshed up it’s job and return’d then execution continued in our lovely journey function and it spit out all of the lyrics. Awesome.

On the other hand, Procs do something very different with returning:


    def journey
      puts 'Oh oh, we\'re halfway there'
        
      next_lyric = Proc.new do 
          puts 'We\'re living on a prayer!' 
          return # <- Notice this little `return` right here. Very important.
      end
      next_lyric.call
        
      puts 'Take my hand, we\'ll make it swear!'
    end
    
    journey
    
    => 'Oh oh, we\'re halfway there'
    => 'We\'re living on a prayer!'

The only difference here is I made next_lyric powered by a Proc instead of Lambda, and it stopped the execution of the outside journey function. Even though the next stanza is inside of the function, it will never ever be sung despite calling journey over and over and over again.

So close, yet so far.

In closing, there are 2 minor differences between Lambas and Procs. If these details are overwhelming, don’t worry. These are tiny nuansces, don’t let them stop you from finishing your journey on becoming a Ruby developer.