Come posso rendere valori non definiti da printf in Perl?
Domanda
Sto cercando un modo elegante per indicare valori non definiti in situazioni in cui numeri formattati di solito rendono. Io lavoro un piccolo esempio. Per cominciare, non è ovviamente possibile utilizzare questo:
#!/usr/bin/perl
use strict;
use warnings;
for my $s (1, 1.2, undef, 1.3) {
printf "%5.2f\n", $s;
}
... perché il 'utilizzare avvertimenti' voi unghie con 'L'utilizzo di valore non inizializzato ...' sulla terza iterazione. Quindi il passo successivo è qualcosa di simile:
#!/usr/bin/perl
use strict;
use warnings;
for my $s (1, 1.2, undef, 1.3) {
printf "%5.2f\n", $s//0;
}
E, ragazzo, ti piace il nuovo operatore 5.10 '//', tra l'altro. Ma che non è proprio quello che voglio, sia, perché il valore di $ s non è zero, è indefinito. Quello che voglio davvero è qualcosa di simile:
#!/usr/bin/perl
use strict;
use warnings;
for my $s (1, 1.2, undef, 1.3) {
printf "%5.2f\n", $s//q();
}
... ma non posso perché questa genera il "Argomento '' non è numerico ..." problema sul terzo valore.
Questo mi porta alla soglia della mia domanda. Io non posso scrivere il codice, naturalmente, che controlla ogni numero emetto per definita-ness, e che crea tutta una stringa di formato printf F-based non% diversa, ma, beh, ... mah.
Qualcuno ha definito un bel modo per affrontare questo tipo di esigenza?
Soluzione
Non credo che ci sia niente di bleah su di esso - è esattamente quello che si vuole fare
.use strict;
use warnings;
my($raw) = [1, 1.2, undef, 1.3];
my($formatted) = [map((defined $_ ? sprintf('%5.2f', $_) : "(undef)"), @$raw)];
print '$formatted: <', join('> <', @{$formatted}), qq(>\n);
Altri suggerimenti
Non è bello, ma mi piacerebbe fare solo come
defined($s) ? printf "%f.2f\n", $s : print "undef\n";
Credo che il bella modo è quello di scrivere / ottenere un PrettyPrinter generico che prende tutto quello che buttare a questo e poi fare:
#!/usr/bin/perl
use strict;
use warnings;
use MyPrettyPrinter;
for my $s (1, 1.2, undef, 1.3) {
print MyPrettyPrinted($s), "\n";
}