# Ruby: new vs initialize

Pour certain c’est une évidence, mais un vieux mail sur la liste de diffusion de ruby_core ma donné envie de me pencher sur la question.

Venant du monde Java (enfin je n’en suis pas encore sorti), je suis un habitué du:

`MacLasse monObjet = MacLasse.new();`

pour Ruby ça devient:

`mon_objet = Mac_lasse.new`

Bon à part le typage dur de java versus le typage dynamique de ruby, pas de gros changement sur l’interprétation de la façon d’instancier un objet entre ces deux langages.

Par contre c’est sur la classe elle même que ça change pas mal.

En java MacLasse ressemble à ça:

      {% highlight java %}
      public class MacLasse {
        public MacLasse(){
          // code a executer lors de l'instanciation de l'objet
        }
      }
      {% endhighlight %}

et en ruby on se retrouve avec ça:

      {% highlight ruby %}
      class MaClasse
        def initialize
          // code a executer lors de l'instanciation de l'objet
        end
      end
      {% endhighlight %}

Cette methode en java s’appel un `constructeur` (ça c’est pour ceux du fond qui suivent pas hein ! ). On l’obtient en définissant une methode portant le même nom que la classe.

Pour ruby, peut importe le nom de la classe, on utilise une methode `initialize`.

Alors `initialize` est-elle une methode de type constructeur ?

Non. et en Java non plus finalement. Ces deux methode ne construisent pas l’instance, elle l’initialise. Elles permettent de préparer l’instance avant de la rendre. En java comme en Ruby, on peut très bien ce passer de ces methodes.

Maintenant on va s’éloigner de Java…

En Ruby on pourrais définir une methode `new` en lieu et place d’@initialize@. Non mais qu’est-ce que je raconte, heureusement y’en a au premier rang qui suivent. Merci.

Je reprend. En ruby on peut surcharger la methode `new` (Object#new) en plus de la methode `initialize`. Le seul hic, c’est qu’il faut faire attention. Cette methode `new` est censé créer l’instance de la class. Il faut donc penser à renvoyer la bonne instance en fin de methode (`new` pour les voisins du radiateur).

Voyons plutôt un petit bout de code:

      {% highlight ruby %}
      class Test_initialize
        def initialize
            "test_initialiaze"
        end
      end

      class Test_new
        def self.new(*args)
            "test_new"
        end
      end

      class Test_new_2
        def self.new(*args)
            "test_new_2"
            Object.new
        end
      end

      test = Test_initialize.new
      puts test.class   # Test_initialize

      test = Test_new.new("args")
      puts test.class   # String

      test = Test_new_2.new("args")
      puts test.class   # Object
      {% endhighlight %}

On le voit assez bien je pense: Surcharger `new` ne doit pas se faire à la légère. Utilisé `initialize` pour initialiser l’instance semble bien plus logique.

Là dessus Ruby montre bien un de ces principe de base qui veux que le langage soit simple et logique. Contrairement a Java ou l’on parle de constructeur en lieu et place de methode d’initialisation.

C’est de la sémantique c’est sur, mais le principe est là. J’aime ruby et j’aime bien java quand même :-)