Files
lespiedsdanslecode/posts/2007/2007-08-09-ruby-new-vs-initialize.md
T
Yannick Francois 29d6558b4e changement de procédé
dans une orientation où le thème change pour toutes les pages
2019-02-23 23:53:36 +01:00

3.3 KiB
Raw Blame History

layout, title, date
layout title date
post Ruby: new vs initialize 2007-08-09

Pour certain cest 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 nen 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 linterprétation de la façon dinstancier un objet entre ces deux langages.

Par contre cest 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 sappel un constructeur (ça cest pour ceux du fond qui suivent pas hein ! ). On lobtient 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 linstance, elle linitialise. Elles permettent de préparer linstance 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 quest-ce que je raconte, heureusement yen 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, cest quil faut faire attention. Cette methode new est censé créer linstance 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 linstance 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 lon parle de constructeur en lieu et place de methode dinitialisation.

Cest de la sémantique cest sur, mais le principe est là. Jaime ruby et jaime bien java quand même :-)