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

my $date = $ARGV[0]; $date or $date = `date --date='1 hour ago' +%Y-%m-%d`; chomp $date;

In this code if the "$date" is NULL then its taking the system date.

But in this code if the hash element is NULL I need to write '0'. For that I tried this way

foreach my $sub_user_error (@db_user_errors) { $worksheet->write( $row, $col, $db_error_data{$hour}{'Submissio +n_user_error'}{$sub_user_error} or 0, $number); $col++; } $row++;

But its not working. Later I tried like

foreach my $sub_user_error (@db_user_errors) { if ($db_error_data{$hour}{'Submission_user_error'}{$sub_user_erro +r} eq "") { $worksheet->write( $row, $col, 0, $number); $col++; } else { $worksheet->write( $row, $col, $db_error_data{$hour}{'Submiss +ion_user_error'}{$sub_user_error}, $number); $col++; } } $row++;

Its working but seems too ugly. Is there any better way for doing this.

Thanks in Advance for helping

Replies are listed 'Best First'.
Re: Need help with Excel::Writer::XLSX in using 'or'
by marioroy (Prior) on May 03, 2016 at 04:00 UTC

    Hi Ravi,

    What is the value for the constant NULL?

    Neither "or 0" or "|| 0" will work if NULL is not a false value.

    Edit

    This question no longer applies. Ravi's code had ... eq "NULL" initially when posting my reply.

Re: Need help with Excel::Writer::XLSX in using 'or'
by Athanasius (Archbishop) on May 03, 2016 at 12:40 UTC

    Hello ravi45722,

    This code snippet has a precedence problem:

    foreach my $sub_user_error (@db_user_errors) { $worksheet->write( $row, $col, $db_error_data{$hour}{'Submissio +n_user_error'}{$sub_user_error} or 0, $number); $col++; }

    If you look at the table in perlop#Operator-Precedence-and-Associativity, you’ll see that logical or has a lower precedence than the comma operator. So if the hash element contains a false value, the expression inside the call to write evaluates to 0, $number, which in turn evaluates to $number — which is not what you want.

    The fix is to use the higher-precedence version of logical or, namely ||:

    #! perl use strict; use warnings; use feature qw( say ); my $hour = 12; my $error = 'Submission_user_error'; my $sub_user_error = 3; my $number = 42; my %db_error_data; $db_error_data{$hour}{$error}{$sub_user_error} = 0; say 'With ||:'; say $db_error_data{$hour}{$error}{$sub_user_error} || 0, $number; say 'With or:'; say $db_error_data{$hour}{$error}{$sub_user_error} or 0, $number;

    Output:

    22:40 >perl 1619_SoPW.pl Useless use of private variable in void context at 1619_SoPW.pl line 1 +7. With ||: 042 With or: 0 22:40 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Confirmed, precedence order :)

      use strict; use warnings; use feature qw( say ); sub _write { my ( $err, $num ) = @_; say "$err, $num"; } my %data; $data{error} = ""; _write( $data{error} || 0, 42 ); $data{error} = "foo bar"; _write( $data{error} || 0, 42 ); $data{error} = "foo baz"; _write( $data{error} or 0, 42 ); # <-- fails __END__ 0, 42 foo bar, 42 Use of uninitialized value $num in concatenation (.) or string at i li +ne 7. foo baz,