Blocks are, well, blocks of code which can be passed into methods. A block can be enclosed by do..end or by brackets {..}. Blocks are often passed to iterators, to perform the same function on members of an array. Consider this code:

[1,2,3].each do |x|
    puts x + 2

>> 3
>> 4
>> 5

The same code can be written by enclosing the block in brackets.

[1,2,3].each do |x| { puts x + 2}

Blocks can be passed to methods. The block is evaluated within the scope of the method. In the example below, notice how the block evaluates the value of y which is set within the method, rather than the value which is set globally.

def say_hello
    y = 3

y = 10
puts say_hello { |x| x + 2 }

>> 5