Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

is it possible to print the "MISSING" label for a non existing hash element, using a single line sprintf command as below (which does not work) ?

Thank you

my $missing = "MISSING"; my %h = ( A => 1.23435 ); my $out = sprintf "%.3E", $h{A} || $missing; warn $out; $out = sprintf "%.3E", $h{B} || $missing; warn $out;

Replies are listed 'Best First'.
Re: Printing non existing hash values as "missing"
by pme (Monsignor) on Jun 10, 2015 at 11:15 UTC
    'NaN' string goes through with '%.3E' format specifier on my old v5.8.8.
    my $missing = "NaN"; my %h = ( A => 1.23435 ); my $out = sprintf "%.3E", $h{A} || $missing; warn $out; $out = sprintf "%.3E", $h{B} || $missing; warn $out;
      Thanks! This can be a solution.
Re: Printing non existing hash values as "missing"
by Anonymous Monk on Jun 10, 2015 at 12:32 UTC
    sub my_sprintf { return defined $_[1] ? sprintf @_ : 'MISSING'; } my %h = ( A => 1.23435 ); my $out = my_sprintf "%.3E", $h{A}; warn $out; $out = my_sprintf "%.3E", $h{B}; warn $out;
      Oops....
      Unlike "printf", "sprintf" does not do what you probably mean when you pass it an array as your first argument. The array is given scalar context, and instead of using the 0th element of the array as the format, Perl will use the count of elements in the array as the format, which is almost never useful - sprintf.
      LOL... who actually knew that? I mean, ******* ****, what the ****!
      sub my_sprintf { return defined $_[1] ? sprintf $_[0], $_[1] : 'MISSING'; }
        That's why I started to get all 2s... :) Thanks
      Thank you, just perfect!
Re: Printing non existing hash values as "missing"
by hippo (Archbishop) on Jun 10, 2015 at 11:17 UTC
    $out = sprintf exists$h{B} ? "%.3E" : '%s' , $h{B} || $missing;

    although there's not much point in using sprintf in that way.

      Thanks, however my problem is that I have a code with a lot of lines with:

      my $out = sprintf "%.3E", $h{A};

      were %h is a hash with nested keys and I would need to add the shortest code to the end of line to print the label MISSING.

        How about:

        my $out = exists $h{$_} ? sprintf "%.3E", $h{$_} : 'MISSING';

        As in:

        my %h = ( A => 1.23435, C => 6.78901, ); for ('A' .. 'C') { my $out = exists $h{$_} ? sprintf "%.3E", $h{$_} : 'MISSING'; warn $out; }

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)