This is my take. It uses yet a different tool set than the two previous posts.

It does perhaps look a bit long, but that's because I've put some comments in the code to explain and motivate some of the code. Without the comments the code is 47 lines (including the empty lines). I admit though that some of the code I put there just to illustrate particular techniques and show what I believe is a healthy programming style.

use strict; use warnings; use Date::Calc::Object qw/ Month_to_Text /; if (@ARGV < 2) { die "$0 STARTDATE ENDDATE FILE\n"; # $0 is the program filename and the newline at the end # makes perl not report filename and line number of the # die call. } my ($start_str, $end_str, $file) = @ARGV; # I prefer to get all parameters directly and don't mess # with @ARGV (or @_ for subroutines) later on. # I also chose to get the dates by parameters rather than # prompting for it. I dislike prompting if parameter # passing will work. my $start = Date::Calc::Object::->new(split /-/, $start_str, 3) or die "Invalid start date\n"; my $end = Date::Calc::Object::->new(split /-/, $end_str, 3) or die "Invalid end date\n"; # Note the colons last in the class name. That helps you # spot typos. (Try removing the use() line above.) my $fh; if (defined $file) { # Use defined() since '0' is a valid file nam +e. open $fh, '>', $file or die "Couldn't open $file for write: $! +"; # Three-argument open is new for Perl 5.6, but recommended. } else { $fh = \*STDOUT; # A reference to a GLOB. See "perldoc -f print +" # and perldata section "Typeglobs and Filehand +les". } # I chose to set STDOUT as default. # A slight change of data structure: my %meals = ( breakfast => [ qw/bagel cereal toast yogurt/ ], lunch => [ qw/sandwich milkshake pb&j hoagie/ ], dinner => [ qw/pasta rice chicken steak/ ], ); # The overloading of Date::Calc::Object objects makes # it easy to use dates as regular counters. for (my $date = $start->clone; $date <= $end; $date++) { my $d = substr(Month_to_Text($date->month), 0, 3) . ' ' . $dat +e->day; print $fh "$d\n"; print '-' x length $d, "\n"; # Since I don't like to repeat myself I abstracted # the meal names. for (qw/ breakfast lunch dinner /) { printf $fh "%-9s: %s\n", ucfirst, $meals{$_}->[rand @{$meals{$_}}] # Note the arrow! ; # The arrow operator above is a dereferencing operator # and you can learn more about references and dereferencin +g # in perlreftut and perlref. # @{$meals{$_}} is also a deref expression and you'll lear +n # about that too in those two documents mentioned above! } print '-' x length $d, "\n\n"; }
Hope I've helped,
ihb

In reply to Re: Critique by ihb
in thread Critique by phenom

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.