Suivant le(s) langage(s) que vous pratiquiez avant de vous mettre à Ruby, les blocs peuvent vous sembler plus ou moins obscurs. Voici un exemple d’utilisation possible, lorsque vous faites du refactoring.

Prenons le programme suivant:

class Bidule
  def un
    puts 'Début de la méthode un'
    puts 'Au milieu de la méthode un'
    puts 'Fin de la méthode un'
  end

  def deux
    puts 'Début de la méthode deux'
    puts 'Au milieu de la méthode deux'
    puts 'Fin de la méthode deux'
  end
end

bidule = Bidule.new
bidule.un
bidule.deux

Voici ce que ça donne quand on le lance:

$ ruby test1.rb 
Début de la méthode un
Au milieu de la méthode un
Fin de la méthode un
Début de la méthode deux
Au milieu de la méthode deux
Fin de la méthode deux

Le problème de la classe Bidule est que ses méthodes un et deux sont identiques (ou presque). On aura donc intérêt à extraire une méthode helper:

class Bidule
  def un
    helper('un')
  end

  def deux
    helper('deux')
  end

  private

  def helper(argument)
    puts "Début de la méthode #{argument}"
    puts "Au milieu de la méthode #{argument}"
    puts "Fin de la méthode #{argument}"
  end
end

Voilà, c’était du refactoring classique.

Maintenant imaginons que la classe Bidule soit ainsi:

class Bidule
  def un
    puts 'Début de la méthode un'
    puts 'Au milieu de la méthode un'
    puts 'Fin de la méthode un'
  end

  def deux
    puts 'Début de la méthode deux'
    puts 'Ceci est le milieu de la méthode deux'
    puts 'Fin de la méthode deux'
  end
end

Vous avez remarqué la différence:

  def un
    #
    puts 'Au milieu de la méthode un'
    #
  end

  def deux
    #
    puts 'Ceci est le milieu de la méthode deux'
    #
  end

Cette fois les méthodes un et deux se distinguent un peu plus, bien que la logique reste identique. On peux donc tirer avantage des blocs:

class Bidule
  def un
    helper('un') { puts 'Au milieu de la méthode un' }
  end

  def deux
    helper('deux') do
      puts 'Ceci est le milieu de la méthode deux'
    end
  end

  private

  def helper(argument, &block)
    puts "Début de la méthode #{argument}"
    block.call
    puts "Fin de la méthode #{argument}"
  end
end

À demain.