Content-type: text/html
Les formats, comme les paquetages et les sous-programmes, sont déclarés plutôt qu'exécutés : ils peuvent donc apparaître à n'importe quel point de vos programmes, mais mieux vaut les regrouper. Ils ont leur propre espace de nommage, bien séparé des autres « types » de Perl. Cela signifie que peuvent coexister une fonction « bidule » et un format « bidule ». Cependant, le nom par défaut d'un format associé à un fichier est le nom du fichier. Par conséquent, le nom par défaut du format pour STDOUT est « STDOUT », et le nom du format par défaut pour le fichier TEMP est « TEMP ». Ils ont l'air semblables, mais ne le sont pas.
Les formats de sortie sont déclarés comme suit :
format NOM = LISTEDEFORMATS .
Si le nom est omis, le format «STDOUT» est alors automatiquement défini. LISTEDEFORMATS consiste en une suite de lignes, chacune d'elle pouvant être de l'un des trois types suivants :
Les lignes-images s'imprimeront exactement comme elles ont été écrites, à l'exception des champs remplacés par des arguments dans ces lignes. Chaque champ d'une ligne-image commence par une arrobe (@) ou un accent circonflexe (^). Ces lignes ne font l'objet d'aucune interprétation. Le champ @, à ne pas confondre avec le symbole de tableau « @ », est le type de champ normal. L'autre type, le champ ^, sert à faire du remplissage multiligne rudimentaire. On définit la longueur de champ en le remplissant avec les caractères « < », « > », ou « | », pour aligner, respectivement, à gauche, à droite, ou au centre. Si la variable excède la longueur spécifiée, elle sera tronquée.
On peut aussi aligner à droite en utilisant le caractère « # », avec un « . » optionnel, pour spécifier un champ numérique : l'alignement se fait sur le « . » décimal. Si la valeur spécifiée pour ces types de champs contient un retour à la ligne, seul le texte jusqu'au retour à la ligne est imprimé. Enfin, le champ spécial «@*» peut être employé pour écrire des valeurs multilignes non tronquées ; il doit apparaître seul sur la ligne.
Les valeurs sont spécifiées sur la ligne suivante, dans le même ordre que les champs images. Les expressions fournissant les valeurs doivent être séparées par des virgules. Les expressions sont toutes évaluées en tant que liste avant que la ligne ne soit traitée. Une seule expression peut donc créer toute une liste d'éléments. Les expressions peuvent être écrites sur plusieurs lignes, à condition de les placer entre parenthèses. En pareil cas, la parenthèse ouvrante doit commencer la première ligne. Si une expression se transforme en nombre avec une partie décimale, et si l'image correspondante spécifie que la partie décimale doit être affichée (c'est-à-dire, n'importe quelle image sauf des « # » sans un « . »), le caractère utilisé pour indiquer la coupure décimale sera toujours déterminé par la locale LC_NUMERIC utilisée. Cela signifie que si l'environnement dans lequel est lancé le script spécifie le français, une virgule sera affichée au lieu du point. Voyez perllocale et ``MISE EN GARDE'' pour les détails.
Les champs images commençant par ^ plutôt que @ subissent un traitement spécial. Avec un champ #, le champ est vide si la valeur n'est pas définie. Pour d'autres types de champs, le ^ permet de choisir un type de remplissage. Au lieu d'avoir une expression arbitraire, la valeur spécifiée doit être une variable scalaire contenant une chaîne de caractères. Perl met autant de texte qu'il peut dans le champ, puis supprime de la chaîne ce qu'il a déjà affiché : à l'appel suivant de la même variable, il affichera la suite des informations. Cela signifie que la variable elle-même est modifiée pendant l'exécution du write(), et elle n'est pas retournée. Vous devez normalement utiliser une séquence de champs alignés verticalement pour afficher un bloc de texte. Vous pouvez terminer le dernier champ par «...», qui apparaîtra si le texte est trop long pour être affiché entièrement. Vous pouvez changer les caractères où il est possible de changer de ligne en utilisant la variable $: (c'est $FORMAT_LINE_BREAK_CHARACTERS si vous utilisez le module English) pour satisfaire vos besoins.
L'utilisation des champs ^ peut produire des enregistrements de longueur variable. Si le texte à formater est court, vous pouvez supprimer les lignes vides en mettant un caractère « ~ » (tilde) n'importe où sur la ligne. Le tilde sera transformé en espace lors de l'affichage. Si vous mettez un deuxième tilde contigu au premier, la ligne sera répétée tant que les champs sur la ligne ne seront pas vides. (si vous utilisez un champ @, l'expression que vous lui avez donné a intérêt à ne pas donner la même valeur tout le temps !)
Les en-têtes de formulaires sont par défaut pris en charge par un format ayant le même nom que le fichier associé, avec «_TOP» ajouté. Il est affiché en haut de chaque page. Voyez ``write'' in perlfunc.
Exemples :
# Un rapport sur le fichier /etc/passwd format STDOUT_TOP = Fichier de mots de passe Nom Login Bureau Uid Gid Maison ------------------------------------------------------------------ . format STDOUT = @<<<<<<<<<<<<<<<<<< @||||||| @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<< $nom, $login, $bureau,$uid,$gid, $maison .
# Un formulaire de rapport de bogue format STDOUT_TOP = Bug Reports @<<<<<<<<<<<<<<<<<<<<<<< @||| @>>>>>>>>>>>>>>>>>>>>>>> $system, $%, $date ------------------------------------------------------------------ . format STDOUT = Sujet : @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $sujet Index : @<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $index, $description Priorité : @<<<<<<<<< Date: @<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $priorite, $date, $description De : @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $de, $description Assigné à : @<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $programmeur, $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<... $description .
Vous pouvez mêler les print() et les write() sur le même canal de sortie, mais vous devez prendre en charge "$-" ($FORMAT_LINES_LEFT) vous-même.
select((select(OUTF), $~ = "Mon_Autre_Format", $^ = "Mon_Top_Format" )[0]);
C'est pas beau, hein ? C'est pourtant assez commun, donc, ne soyez pas trop surpris quand vous le verrez. Vous pouvez à la limite utiliser une variable temporaire pour pouvoir récupérer le filehandle précédent (c'est une bien meilleure approche en général, non seulement car vous avez plusieurs étapes pour pouvoir faire joujou avec le debuggeur) :
$ofh = select(OUTF); $~ = "Mon_Autre_Format"; $^ = "Mon_Top_Format"; select($ofh);
Si vous utilisez le module English, vous pouvez même lire les noms de variables :
use English; $ofh = select(OUTF); $FORMAT_NAME = "Mon_Autre_Format"; $FORMAT_TOP_NAME = "Mon_Top_Format"; select($ofh);
Mais il y a toujours les drôles de select(). Donc, utilisez juste le module FileHandle. Maintenant, vous pouvez accéder a ces variables spéciales en utilisant des méthodes en minuscules :
use FileHandle; format_name OUTF "Mon_autre_Format"; format_top_name OUTF "Mon_Top_Format";
format Ident = @<<<<<<<<<<<<<<< &commify($n) .
Pour avoir un vrai @ ou ^ dans un champ, faites :
format Ident = J'ai un @ ici. "@" .
Pour centrer une ligne entière de texte, faites :
format Ident = @||||||||||||||||||||||||||||||||||||||||||||||| "Une ligne de texte" .
Il n'existe pas de façon prédéfinie de dire « mets ça à droite de la page, quelle que soit sa largeur » : vous devez spécifier où chaque chose doit aller. Dans les cas vraiment désespérés on peut générer un format à la volée, en se basant sur le nombre de colonnes, pour ensuite l'évaluer avec eval() :
$format = "format STDOUT = \n" . '^' . '<' x $cols . "\n" . '$entry' . "\n" . "\t^" . "<" x ($cols-8) . "~~\n" . '$entry' . "\n" . ".\n"; print $format if $Debugging; eval $format; die $@ if $@;
qui générera un format ressemblant a quelque chose dans ce goût-là :
format STDOUT = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $entry ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ $entry .
Voici un petit programme qui fait a peu près la même chose que fmt(1) :
format = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ $_
.
$/ = ''; while (<>) { s/\s*\n\s*/ /g; write; }
Voici une première stratégie : si vous avez un pied de page de taille constante, vous pouvez vérifier $FORMAT_LINES_LEFT avant chaque write() et imprimer le pied de page quand c'est nécessaire.
Une autre stratégie consiste à ouvrir un pipe sur soi-même, utilisant "open(MOIMEME, "|-")" (référez vous a ``open()'' in perlfunc) et à ne faire que des write() sur MOIMEME plutôt que STDOUT. Faites en sorte que le processus fils remanie STDIN pour ajouter le pied de page comme il vous plaît. Ce n'est pas très pratique, mais c'est faisable.
Par exemple :
$str = formline <<'END', 1,2,3; @<<< @||| @>>> END
print "Yo, je viens de mettre `$^A' dans l'accumulateur !\n";
Ou faire une routine swrite(), qui est à write() ce que sprintf() est à printf(), comme suit :
use Carp; sub swrite { croak "utilisation : swrite IMAGE ARGUMENTS" unless @_; my $format = shift; $^A = ""; formline($format,@_); return $^A; }
$string = swrite(<<'END', 1, 2, 3); Check me out @<<< @||| @>>> END print $string;
Les variables lexicales (déclarées avec « my ») ne sont pas visibles dans un format sauf celui-ci est déclaré dans le champ de vision de la variable lexicale. Ils n'étaient pas visibles du tout avant la version 5.001.
Les formats sont le seul morceau de Perl qui utilisent de façon inconditionnelle les informations provenant de la locale d'un programme. Si l'environnement du programme spécifie une locale LC_NUMERIC, elle sera toujours utilisée pour spécifier le point décimal dans une sortie formatée. Perl ignore tout simplement le reste de la locale si le pragma "use locale" n'est pas utilisé. Les sorties formatées ne peuvent pas prendre en compte ce pragma car il est lié a la structure de bloc du programme, et, pour des raison historiques, les formats sont définis hors de cette structure. Référez-vous à perllocale pour plus d'informations sur la gestion des locales.