Como posso renderizar valores indefinidos do printf em Perl?
Pergunta
Estou procurando uma maneira elegante de denotar valores indefinidos em situações em que números formatados geralmente renderizam. Vou trabalhar um pequeno exemplo. Para iniciantes, é claro que você não pode usar isso:
#!/usr/bin/perl
use strict;
use warnings;
for my $s (1, 1.2, undef, 1.3) {
printf "%5.2f\n", $s;
}
... Porque o 'Use avisos' prega você com 'uso de valor não inicializado ...' na terceira iteração. Então, o próximo passo é algo assim:
#!/usr/bin/perl
use strict;
use warnings;
for my $s (1, 1.2, undef, 1.3) {
printf "%5.2f\n", $s//0;
}
E, garoto, eu gosto do novo operador 5.10 '//', a propósito. Mas também não é isso que eu quero, porque o valor de $ s não é zero, é indefinido. O que eu realmente quero é algo assim:
#!/usr/bin/perl
use strict;
use warnings;
for my $s (1, 1.2, undef, 1.3) {
printf "%5.2f\n", $s//q();
}
... mas não posso porque isso gera o problema "argumento" "não é numérico ..." no terceiro valor.
Isso me leva à porta da minha pergunta. É claro que posso escrever um código que verifique todos os números que emite em busca de definição, e que cria uma string de formato PrintF não baseado em f, não baseado em F totalmente diferente, mas, bem, ... eca.
Alguém definiu uma boa maneira de lidar com esse tipo de exigência?
Solução
Eu não acho que há nada que nojo Sobre isso - é exatamente o que você quer fazer.
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);
Outras dicas
Não é bonito, mas eu apenas faria como
defined($s) ? printf "%f.2f\n", $s : print "undef\n";
Eu acho que o legais O caminho é escrever/obter uma bela iminente genérica que leva o que você jogar nele e depois fazer:
#!/usr/bin/perl
use strict;
use warnings;
use MyPrettyPrinter;
for my $s (1, 1.2, undef, 1.3) {
print MyPrettyPrinted($s), "\n";
}