Section 7.3

L'état, et self

Les méthodes d'un archetype travaillent sur l'exemplaire qui les appelle — self, c'est lui.

Un archetype ne porte pas que des champs : il porte des méthodes, et chacune travaille sur l’exemplaire qui l’appelle.

archetype Personnage {
    prenom: str;
    energie: int;

    saluer() {
        Console.print(text: $"Je suis {self.prenom}, énergie {self.energie}.");
    }

    fatiguer(cout: int) {
        self.energie := self.energie - cout;
    }
}

@entry(demarrer)
object MonProgramme {
    demarrer() {
        var simon := Personnage(prenom: "Simon Magus", energie: 10);
        var helene := Personnage(prenom: "Hélène", energie: 7);

        simon.fatiguer(cout: 3);

        simon.saluer();
        helene.saluer();
    }
}

self désigne cet exemplaire-ci

Depuis la 1.2.1, self était une formule qu’on recopiait. La voici qui prend tout son sens :

saluer() {
    Console.print(text: $"Je suis {self.prenom}, énergie {self.energie}.");
}

Quand simon.saluer() s’exécute, self est Simon ; quand helene.saluer() s’exécute, self est Hélène. Une seule méthode, écrite une fois, et chaque exemplaire y passe avec ses propres valeurs. Dans un object, self désignait l’unique instance ; dans un archetype, il désigne celle qui appelle.

L’état change, et il reste

fatiguer(cout: int) {
    self.energie := self.energie - cout;
}

simon.fatiguer(cout: 3) retranche 3 à l’énergie de Simon — et à la sienne seulement : l’exemple affiche 7 pour Simon, 7 pour Hélène, chacun par son chemin. La modification survit à l’appel : l’exemplaire porte son état, les méthodes le font vivre.

Les champs se modifient aussi de l’extérieur — simon.energie := 3; est permis. Passer par une méthode n’est pas une obligation du langage, c’est une discipline : fatiguer dit pourquoi l’énergie baisse, là où l’affectation nue ne dit rien.

Deux noms ne font pas deux exemplaires

var alias := simon;
alias.fatiguer(cout: 3);

Après cela, simon.energie a baissé aussi — alias et simon désignent le même exemplaire. Copier une variable ne copie pas le personnage : il n’y a toujours qu’un Simon, atteint par deux noms. C’est la même vérité que le = de la sous-section précédente, vue de l’autre côté : l’identité est celle de l’exemplaire, pas celle du nom.

À vous

  • Fatiguez Hélène de 2 et vérifiez que Simon n’a pas bougé.
  • Ajoutez une méthode reposer(gain: int) qui rend l’énergie, et faites se reposer Simon.
  • Écrivez var alias := simon; alias.fatiguer(cout: 5); puis faites saluer simon : son énergie a baissé. Deux noms, un seul personnage.
  • Faites saluer un personnage dont l’énergie est tombée à zéro — rien ne l’interdit encore. La sous-section suivante donne au constructeur le pouvoir d’imposer des règles à la naissance ; la section 8 donnera aux méthodes celui de refuser.