---
layout: post
title: Ruby if unless
---

Une des choses très agréable avec [Ruby](http://ruby-lang.org) c'est ça syntaxe. Un des mots bien particulier en Ruby est `unless`.

Je partage tout à fait l'avis de ce billet [Unless, The Abused Ruby Conditional](http://railstips.org/2008/12/1/unless-the-abused-ruby-conditional) `unless` c'est bien, très bien même dans certain cas, mais en abuser c'est mal. Ce mot peut rendre les choses plus lisible tout comme il pourrait les compliquer.

Une condition doit représenter une intention, unless permet de le faire, mais cela doit rester une intention.

<pre>
  {% highlight ruby %}
    xml.updated @items.first.updated_at.xmlschema unless @items.empty?
  {% endhighlight %}
</pre>

Ce code, extrait de la classe feed.atom.builder de [Typo](http://typosphere.org) est une bonne utilisation de `unless`. On évite ainsi le vilain:

<pre>
  {% highlight ruby %}
    xml.updated @items.first.updated_at.xmlschema if !@items.empty?
  {% endhighlight %}
</pre>

Un peu comme, et dans la même classe, nous avons un peu plus haut:

<pre>
  {% highlight ruby %}
    if(not this_blog.blog_subtitle.blank?)
      xml.subtitle this_blog.blog_subtitle, "type"=&gt;"html"
    end
  {% endhighlight %}
</pre>

Assez étrange, nous aurions pu avoir plutôt

<pre>
  {% highlight ruby %}
    unless this_blog.blog_subtitle.blank?
      xml.subtitle this_blog.blog_subtitle, "type"=&gt;"html"
    end
  {% endhighlight %}
</pre>

Voir

<pre>
  {% highlight ruby %}
    xml.subtitle this_blog.blog_subtitle, "type"=&gt;"html" unless this_blog.blog_subtitle.blank?
  {% endhighlight %}
</pre>

Il y a part contre dans la méthode `ping_article!` du modèl `blog.rb` une mauvaise utilisation de `unless` (à mon avis)

<pre>
  {% highlight ruby %}
    unless global_pings_enabled? &amp;&amp; settings.has_key?(:url) &amp;&amp; settings.has_key?(:article_id)
      throw :error, "Invalid trackback or trackbacks not enabled"
    end
  {% endhighlight %}
</pre>

et une bonne.

<pre>
  {% highlight ruby %}
    unless article.allow_pings?
      throw :error, "Trackback not saved"
    end
  {% endhighlight %}
</pre>

Pour la bonne, rien à dire. Par contre, la première n'exprime pas assez clairement l'intention.

<pre>
  {% highlight ruby %}
    if !global_pings_enabled? || !settings.has_key?(:url) || !settings.has_key?(:article_id)
      throw :error, "Invalid trackback or trackbacks not enabled"
    end
  {% endhighlight %}
</pre>

Je trouve que là c'est plus clair, on comprend mieux que si l'une des trois conditions n'est pas rempli, on lève un exception.

_Tout ceci est une histoire de gout peut-être, vous en pensez quoi ?_

