http://qs1969.pair.com?node_id=1193701

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

I figured out how to fix an issue I first had shortly after I began programming in Perl and that has plagued me since, but I'm at a loss to explain how this could possibly matter. This is definitely one for Monks more knowledgeable than I, and especially (I presume) those familiar with the pp module. I'm using Strawberry Perl on Windows 7, and of course can provide more information than that if necessary. I simply enter pp -o my_name.exe my_script.pl on the command line.

When I have the following code and and am trying to use pp to make an .exe, it makes the .exe, but the .exe doesn't seem to do anything at all when run (it won't even pause on the my $pause_here = <STDIN> line here.

#!/usr/bin/perl use utf8; use 5.022; use strict; use List::Util qw(max); use Date::Cal +c qw(Delta_Days); say "FINISHED"; my $pause_here = <STDIN>;

However, when I do the following, it works just fine, makes the .exe, and the .exe runs and performs as expected. Yes, the only difference is the one newline after use 5.022.

#!/usr/bin/perl use utf8; use 5.022; use strict; use List::Util qw(max); use Date::Calc qw(Delta_Days); say "FINISHED"; my $pause_here = <STDIN>;

It's the use Date::Calc qw(Delta_Days) that always caused me trouble. Without it, and even with all the other use statements on a single line, it also all works perfectly fine.

#!/usr/bin/perl use utf8; use 5.022; use strict; use List::Util qw(max); say "FINISHED"; my $pause_here = <STDIN>;

Am I crazy? Can anyone else repeat this behavior or explain it?

Now I always put one use statement per line anyway, but I had this problem in several old scripts I wrote where I wasn't yet in that habit, and I never found this as the "fix" until now. This plagued me so much until now that I literally have written and rewritten (because of course it didn't work the first time I reinvented the wheel) my own days_diff subroutine and simple single day difference test of it to deal with this.

use utf8; use 5.022; use strict; use warnings; for (my $year=1970; $year<=2100; $year++) { for (my $month=1; $month<=12; $month++) { for (my $day=1; $day<=31; $day++) { next if ( ($month == 2 && ($day == 30 || $day == 31)) || ($month == 2 && $day == 29 && ($year%4 != 0 || ($year +%100 == 0 && $year%400 != 0))) || ($month == 4 && $day == 31) || ($month == 6 && $day == 31) || ($month == 9 && $day == 31) || ($month == 11 && $day == 31) ); my $date1 = $month. "/" . $day . "/" . $year; my $date2 = $month . "/" . ($day+1) . "/" . $year; $date2 = ($month+1) . "/1/" . $year if ( ($day+1 == 32) || ($month == 2 && ($day+1 == 30 || $day+1 == 31)) || ($month == 2 && $day+1 == 29 && ($year%4 != 0 || ($ye +ar%100 == 0 && $year%400 != 0))) || ($month == 4 && $day+1 == 31) || ($month == 6 && $day+1 == 31) || ($month == 9 && $day+1 == 31) || ($month == 11 && $day+1 == 31) ); $date2 = "1/1/" . ($year+1) if ($month+1 == 13 && $day+1 +== 32); my $difference = days_diff($date2, $date1); say "$date1\t$date2\t$difference" if ($difference != 1); } } } say "Hit Enter to quit."; my $pause = <STDIN>; sub days_diff { my ($month1, $day1, $year1) = split /\//, $_[0]; my ($month2, $day2, $year2) = split /\//, $_[1]; # The Date::Calc module function "Delta_Days" was used for this an +d worked great, but it would not compile in to an .exe using pp. # use Date::Calc qw(Delta_Days); # use is here for convenient copy +/paste # return Delta_Days($year2, $month2, $day2, $year1, $month1, $day1 +); # This crude (not precise over long timeframes or short ones spann +ing the end of February and March, but this was fine for the applicat +ion) method was used for a long time, # but it fails (in an unacceptable way) when subtracting a day tha +t falls on the 1st of the next month from a day that falls on the 31s +t the prior month (gives -0, not -1), # return sprintf("%.0f", ($year1-$year2)*365.25+($month1-$month2)* +365.25/12+($day1-$day2)); # Here a Gergorian calendar date to Julian day number conversion i +s used on both dates and then they are subtracted. # https://en.wikipedia.org/wiki/Julian_day#Converting_Julian_or_Gr +egorian_calendar_date_to_Julian_day_number use POSIX qw(floor); # use is here for convenient copy/paste my $a1 = floor((14-$month1)/12); my $a2 = floor((14-$month2)/12); my $y1 = $year1 + 4800 - $a1; my $y2 = $year2 + 4800 - $a2; my $m1 = $month1 + 12*$a1 - 3; my $m2 = $month2 + 12*$a2 - 3; my $JDN1 = $day1 + floor((153*$m1+2)/5) + 365*$y1 + floor($y1/4) - + floor($y1/100) + floor($y1/400) - 32045; my $JDN2 = $day2 + floor((153*$m2+2)/5) + 365*$y2 + floor($y2/4) - + floor($y2/100) + floor($y2/400) - 32045; return $JDN1-$JDN2; }

Just another Perl hooker - But the purist monks keep telling me I should do it for love, not money.