2010-11-09 21 views
2

Pour un formatage de sortie simple, j'ai tendance à utiliser printf où j'utilisais l'écriture/format au moment de Perl 4. Cependant, il semble parfois la solution la plus simple pour des nombres variables de lignes de sortie par enregistrement. Par exempleQu'est-ce qu'un remplacement de `write` et` format` dans Perl 5?

#!/usr/bin/perl 
use strict; 
use warnings; 

my ($lorem, $aprille); 

format = 
@# ^<<<<<<<<<<<<<<<<<<<<<<<< | ^<<<<<<<<<<<<<<<<<< 
$.,$aprille     , $lorem 
    ^<<<<<<<<<<<<<<<<<<<<<<<< | ^<<<<<<<<<<<<<<<<<< ~~ 
    $aprille     , $lorem 
          | 
. 

while(<DATA>) { 
    ($aprille, $lorem) = split(/\|/, $_, 2); 
    write; 
} 

__DATA__ 
WHAN that Aprille with his shoures soote  |Lorem ipsum dolor sit amet, 
The droghte of Marche hath perced to the roote,|consectetur adipisicing elit, 
And bathed every veyne in swich licour,  |sed do eiusmod tempor 
Of which vertu engendred is the flour;   |incididunt ut labore et dolore 
Whan Zephirus eek with his swete breeth  |magna aliqua. Ut enim ad minim 
Inspired hath in every holt and heeth   |veniam, quis nostrud 
The tendre croppes, and the yonge sonne  |exercitation exercitation 
Hath in the Ram his halfe cours y-ronne,  |ullamco laboris nisi ut ali- 
And smale fowles maken melodye,    |quip ex ea commodo conse- 
That slepen al the night with open ye,   |quat. Duis aute irure dolor 
So priketh hem nature in hir corages:   |in reprehenderit in volup- 
Than longen folk to goon on pilgrimages,  |tate velit esse cillium dol- 
And palmers for to seken straunge strondes, |ore eu fugiat nulla pariatur. 
To ferne halwes, couthe in sondry londes;  |Lorem ipsum dolor sit amet, 
And specially, from every shires ende   |consectetur adipisicing elit, 
Of Engelond, to Caunterbury they wende,  |sed do eiusmod tempor 
The holy blisful martir for to seke,   |incididunt ut labore et dolore 
That hem hath holpen, whan that they were seke.|magna aliqua. Ut enim ad minim 
And now for something completely different. Nice plumage.|Norwegian blue. 

Produit

1 WHAN that Aprille with | Lorem ipsum dolor 
    his shoures soote   | sit amet, 
           | 
    2 The droghte of Marche  | consectetur 
    hath perced to the roote, | adipisicing elit, 
           | 
    3 And bathed every veyne in | sed do eiusmod 
    swich licour,    | tempor 
    ... 
    19 And now for something  | Norwegian blue. 
    completely different.  | 
    Nice plumage.    | 

Notez que la fiche 19 occupe trois lignes.

Qu'est-ce qu'une méthode perl5ish concise équivalente pour faire ce qui précède sans utiliser l'écriture et le format?

+7

écriture et format de travail dans Perl 5. Pourquoi voulez-vous/besoin de le changer? – Cfreak

+0

Les gens disent souvent qu'il y a des problèmes d'écriture et de format. Les gens se réfèrent souvent à lui comme obsolète. Je l'ai vu assez souvent pour le croire. Je ne suis pas sûr de ce que sont les problèmes - ce qui en soi est également une raison d'envisager des solutions de rechange. – RedGrittyBrick

+3

'write/format' ne sont pas dépréciés, ils sont juste ésotériques – mob

Répondre

2

Le principal problème avec les formats est le recours aux variables globales. Pour les autres problèmes avec les formats, voir pages 449 - 454 de Perl Best Practices.

La solution moderne serait Perl6::Form. Ceci est un backport de ce qu'ils projettent pour Perl 6.

Ce qui suit est une traduction approximative de votre code de format à Perl6::Form. Je ne sais pas Perl6::Form très bien, donc il peut y avoir des moyens de faire mieux ou plus fidèle à votre exemple original:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Perl6::Form; 

while(<DATA>) { 
    my ($aprille, $lorem) = split(/\|/, $_, 2); 
    print form(
     "{>} {[[[[[[[[[[[[[[[[[[[[[[[[} | {[[[[[[[[[[[[[[[[[[}", 
     $., $aprille,     $lorem, 
     "        |      ", 
    ); 
} 

__DATA__ 
WHAN that Aprille with his shoures soote  |Lorem ipsum dolor sit amet, 
The droghte of Marche hath perced to the roote,|consectetur adipisicing elit, 
And bathed every veyne in swich licour,  |sed do eiusmod tempor 
Of which vertu engendred is the flour;   |incididunt ut labore et dolore 
Whan Zephirus eek with his swete breeth  |magna aliqua. Ut enim ad minim 
Inspired hath in every holt and heeth   |veniam, quis nostrud 
The tendre croppes, and the yonge sonne  |exercitation exercitation 
Hath in the Ram his halfe cours y-ronne,  |ullamco laboris nisi ut ali- 
And smale fowles maken melodye,    |quip ex ea commodo conse- 
That slepen al the night with open ye,   |quat. Duis aute irure dolor 
So priketh hem nature in hir corages:   |in reprehenderit in volup- 
Than longen folk to goon on pilgrimages,  |tate velit esse cillium dol- 
And palmers for to seken straunge strondes, |ore eu fugiat nulla pariatur. 
To ferne halwes, couthe in sondry londes;  |Lorem ipsum dolor sit amet, 
And specially, from every shires ende   |consectetur adipisicing elit, 
Of Engelond, to Caunterbury they wende,  |sed do eiusmod tempor 
The holy blisful martir for to seke,   |incididunt ut labore et dolore 
That hem hath holpen, whan that they were seke.|magna aliqua. Ut enim ad minim 
And now for something completely different. Nice plumage.|Norwegian blue. 
+0

Cela fausse quelque peu le problème. Les variables qui apparaissent dans les lignes de valeurs d'un format ne doivent pas nécessairement être globales. Cela ressemble plus à la façon dont les fonctions nommées dans '% SIG' doivent être dans la table des symboles d'un paquet (' main :: 'par défaut). De même, les valeurs '$ ~' et '$ ^' par poignée reflètent les noms de paquetages. Vous ne pouvez pas vous en tirer avec '$ ~ = * SOMETHING {FORMAT}', bien que vous puissiez faire 'local $ ~ =" SOMETHING "'. – tchrist

+0

Je * aime * l'approche 'Perl6 :: Form'; merci de l'avoir posté. J'ai souvent écrit des fonctions qui prennent un premier argument «formline» et utilisé le reste des positions pour remplir la ligne de valeurs. – tchrist

+0

Owens: Merci, la documentation pour 'Perl6 :: Form' est beaucoup plus vaste et que perldoc perlform' - amusant aussi. Je pense que votre exemple répond très bien à ma question. L'utilisation de 'Perl6 :: Form' me semble un outil plus perl5ish et plus capable que les' write' et 'format' hérités de Perl4. – RedGrittyBrick

3

La principale chose que perl5 ajouté ci-dessus perl4's format et write est formline. Il y a quelques autres subtilités, y compris $^A, les formats numériques, et la portée du paquet, mais ce sont principalement des fluff non essentiels. L'ensemble actuel des directives de mise en forme est seulement un peu plus grande que celle de perl4:

@ start of regular field 
^ start of special field 
< pad character for left justification 
| pad character for centering 
> pad character for right justification 
# pad character for a right justified numeric field 
0 instead of first #: pad number with leading zeroes 
. decimal point within a numeric field 
... terminate a text field, show "..." as truncation evidence 
@* variable width field for a multi-line value 
^* variable width field for next line of a multi-line value 
~ suppress line with all fields empty 
~~ repeat line until all fields are exhausted 

D'autres améliorations peu connues incluent le soutien pour LC_NUMERIC local, pouvoir utiliser un {} bloc -delimited pour faciliter l'alignement, et en utilisant un \r forcer un vrai saut de ligne. J'utilise encore format de temps en temps. Voici un peu d'un programme que j'ai écrit il y a seulement quelques semaines.

sub init_screen() { 
    our %Opt; 
    my $cols; 

    if ($Opt{width}) { 
     $cols = $Opt{width}; 
    } 
    elsif (am_unixy()) { 
     ($cols) = `stty size 2>&1` =~ /^\d+ (\d+)$/; 
    } 
    else { 
     # FALLTHROUGH to ||= init on next line 
    } 

    $cols ||= 80; # non-unix or stty error 
    $cols -= 2; 

    my $format = "format STDOUT = \n" 
       . ' ^' . '<' x ($cols-4) . "\n" 
       . '$_' . "\n" 
       . "  ^" . "<" x ($cols-6) . "~~\n" 
       . '$_' . "\n" 
       . ".\n" 
       . "1;" # for true eval return 
       ; 

    eval($format) || die; 
} 

Le code pour la construction du format dynamique en fonction de la largeur de l'écran actuel pourrait être plus jolie, mais il est toujours utile.

+0

Merci pour la réponse instructive et intéressante. Cela compte évidemment comme un contre-exemple à la prémisse de ma question. – RedGrittyBrick