Section 9.3

Du texte au nombre, et retour

toInt lève une ParseError quand le texte n'est pas un nombre, toText rend une str sur laquelle on peut encore travailler.

Un texte qui ressemble à un nombre n’est pas un nombre : "3" * 2 n’a aucun sens et le compilateur le dit. Le passage se demande, dans un sens comme dans l’autre — et l’un des deux peut échouer.

import { StrText } from "std/extensions/str-text.arc";
import { IntText } from "std/extensions/int-text.arc";

extend archetype str StrText;
extend archetype int IntText;

@entry(demarrer)
object MonProgramme {
    demarrer() {
        var mesure := "3";
        var doses := mesure.toInt();

        Console.print(text: $"le double : {doses * 2}");
        Console.print(text: $"au registre : [{doses.toText().alignedRight(width: 4)}]");

        try {
            var faux := "trois".toInt();
            Console.print(text: $"jamais atteint : {faux}");
        } catch (erreur: ParseError) {
            Console.print(text: $"refusé : {erreur.message}");
        }
    }
}

Deux fichiers, deux extend

import { StrText } from "std/extensions/str-text.arc";
import { IntText } from "std/extensions/int-text.arc";

extend archetype str StrText;
extend archetype int IntText;

toInt est une méthode de str, toText une méthode de int : ce sont deux types différents, donc deux paquets, donc deux lignes chacune. Les en-têtes s’allongent, et c’est le prix d’un noyau minuscule : ce que le programme utilise, il le nomme.

toInt peut échouer, donc il lève

"trois".toInt() ne rend pas zéro, ne rend pas une valeur par défaut : il lève une ParseError.

refusé : 'trois' is not a valid integer

C’est le raisonnement de la 8.2 appliqué une fois de plus : un texte dont on demande explicitement qu’il soit un nombre, et qui ne l’est pas, est une vraie erreur — pas une absence à marquer d’un zéro, puisque zéro serait un nombre parfaitement plausible et que rien ne le distinguerait d’un "0" réussi.

D’où le try / catch autour de l’appel, écrit exactement comme en 8.1, avec un archetype d’erreur fourni par le langage.

toText, quand l’interpolation ne suffit plus

L’interpolation convertit déjà : $"{doses}" affiche 3 sans qu’on demande rien. Alors pourquoi toText ?

Parce que l’interpolation rend un texte fini, et toText une str sur laquelle on peut encore travailler :

doses.toText().alignedRight(width: 4)

alignedRight complète à gauche jusqu’à la largeur demandée — de quoi mettre des nombres en colonne. Il vient de StrText, comme tout le reste de la 9.1 : dès que toText a rendu une str, le texte sait faire tout ce que str sait faire.

Ce que l’interpolation ne convertit pas

Quatre types passent dans un trou de $"…" : int et ses largeurs, float, bool et str. Un archetype à vous n’en fait pas partie, et le refus est explicite :

error[T032]: an interpolated hole of type 'Potion' has no text conversion: only 'int' and its
widths, 'float', 'bool' and 'str' convert -- give the value a 'str' first

« Donnez d’abord une str à la valeur » : une méthode à vous, sur votre archetype, qui rend le texte que vous voulez voir. Le langage ne devine pas à quoi ressemble une potion écrite.

Le reste de la bibliothèque, au même endroit

Même mécanique, autres fichiers :

  • toFloat() sur une str — StrReal, dans std/extensions/str-real.arc ;
  • squareRoot() et floored() sur un float64 — FloatMath, dans std/extensions/float-math.arc ;
  • toText() pour un float64 ou un bool — FloatText et BoolText, chacun dans le sien.

À vous

  • Donnez "3 doses" à toInt : le texte n’est pas un nombre entier, donc ParseError. Il faut d’abord couper — la 9.2 a montré comment.
  • Retirez le try / catch et laissez l’erreur filer : le programme s’arrête en la nommant, comme en 8.2.
  • Mettez mesure à "1234" en gardant width: 4, puis width: 2 : un texte plus long que la largeur demandée n’est pas rogné, il sort tel quel.
  • Attrapez la ParseError et rendez 0 à la place : c’est votre décision de traiter l’absence ainsi, prise en connaissance de cause, et non celle du langage prise à votre place.