I think jethro's comments are on traget with your error. I'll make a couple of other suggestions. Not trying to be hyper critical, just helpful.

1. When debugging stuff where you are getting run time messages to STDERR and printing stuff to STDOUT at the same time, often it is helpful to turn buffering off by putting $|=1; at the top of your code. STDERR is not buffered while STDOUT is and thus the order of the stuff on the screen won't reflect the actual time sequence of events unless you turn the buffering off.

2. I believe that your command loop could be improved. You've set main up as a subroutine that you call when you want to get started again (happens in a bunch of places in the code). This approach has a problem, every time you call main(), you leave some stuff on the stack. To illustrate the issue, make these 2 small changes to your code:

} elsif ( $option == 8 ) { return(0); ######change here } else { print "Error: Option $option invalid\n"; <STDIN>; main(); print "leftover\n"; ###change here <STDIN>; }
Now run the program and select an invalid option a couple of times, then select 8, the exit. You will see that "leftover" gets printed a few times these are the exits from main() that never happened before. Now in this program, I doubt that this would become any big deal. But this probably would get to be a problem in a long lived program that called main() a lot.

3. There are many ways to Rome on command loops. I wrote some quick code for you to show another way to do this - many variations are possible. A general philosophy of mine when dealing with user input: validate the heck out of it before trying to use it and be flexible in allowing users to enter whitespace around input.

#!/usr/bin/perl -w use strict; while (display_menu(), (my $option = <STDIN>) ) { $option =~ s/^\s*//; #no leading whitespace $option =~ s/\s*$//; #no trailing whitespace #(no need for chomp) as \r\n\t\f #and space all count as \s chars if ( ($option !~ /^\d$/) or ($option <=0) or ($option >2) ) { display_menu_error ("ERROR: illegal option: $option selected\n" +); next; } print "opt number is $option\n"; #just a debug statement action1() if $option == 1; action2() if $option == 2; #etc..... #note: this compare is so fast, that no need to clutter things #up with elseif statements } sub action1 { clear_screen(); print "OPERATION 1 ok: \n"; #could be an error message } sub action2 { clear_screen(); print "did action 2\n"; } sub clear_screen { if ( $^O =~ /MSWin32/ ) { system('cls'); } else { system('clear'); } } sub display_menu_error { my $msg = shift; clear_screen(); print "$msg\n"; } sub display_menu { print "Cleveland State CC Computer Repairs\n\n"; print "Version xxxxxxx\n", "Copyleft 2009 Adam Jimerson & Andy Arp\n"; print "----------------------------\n", "Main Menu, To make a selection specify the number for that action +\n"; print "1. Add New Computer to Database\n"; print "2. Edit Computer Status in Database\n"; print "3. Remove a Computer from Database\n"; print "4. Look up Computer Information\n"; print "5. List All Repair Requests\n"; print "6. Print Final Report For Customer\n"; #this should be don +e to ensure we provide information on a repair #to the customer on paper print "7. Check Computer Status\n"; print "8. Quit the program\n"; print "Action: "; }
Each action does what it does and then returns to the main command loop. Then program just falls through any $option compare statements and goes back to reprompt. So when one of these "action" subroutines finishes, either with some error message or success message, just return(), don't call main() again!

I tried to incorporate your idea of clearing the screen after each action. Although I remember answering your question about how to do this in XP, I personally would find that interface annoying and wouldn't do it that way. But this is your app, not mine! Go for it!

Anyway, main shouldn't be a subroutine.

3. I would move the database connection and authentication stuff to the top of program. Looks like every action depends upon DB. No need to do this multiple times and no need to bother user entering in a whole bunch of stuff only to find out later that operation is going to fail because you can't connect to the database.

4. I don't know how your experience will work out with FORMAT, but when I first saw this, I thought how cool! I wrote one program with it. Then decided that it was more hassle than other ways. I find that printf, sprintf do a better job for me. Your mileage may vary.


In reply to Re: Trouble with an array inside a format call by Marshall
in thread Trouble with an array inside a format call by vendion

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.