Greetings,
I'm a former hardware guy (embedded C & C++ experience mainly) trying to get up to speed with Java and Perl for a set of graduate courses.

I've written up a Perl script that simulates a scheduling algorithm, the script consists of two primary loops the first to parse process/event info from a file, the second to schedule each event. The first loop executes fine, but I'm having issues getting the script to run with my second loop - since I'm doing this in Perl (with no main block) I'm concerned it may have something to do with the scope of my vars (my three primary data structures are a 2d array used as an array of stacks, and two hashes used to reference event dependencies.

I am using Eclipse/EPIC/ActiveState Perl 5.8.6 to debug my script. I'm a noob at this, although I've had some experience using regular expressions/Perl in a Unix environment, admittedly at the moment I'm completely stuck...
Parse loop (appears to work fine):

foreach $line (<FILE>) { chomp $line; if ($line =~ m/(\d)-(\d)->(\d)-(\d)/) { #create local sender and receiver vars my $sp = "$1-$2"; my $rp = "$3-$4"; #update sender and receiver hashes $sender{$sp} = $rp; $receiver{$rp} = $sp; print "enter $sender{$sp}->$receiver{$rp} in dependency hashes +\n"; } elsif($line =~ m/(\d)-(\d)/) { #create local process var my $p = "$1-$2"; #queue process on @p_s multi-dimensional array unshift (@{$p_s[$1]},$p); print "unshift $p_s[$1][0] onto process array\n"; $numevents++; } else { print "\nunmatched line: $line \n"; chomp($line); #remove empty newlines in input file } }

Scheduling loop (script produces no output with this included)
while($timestamp <= $numevents) { print "\ntimestamp: $timestamp, numevents: $numevents\n"; foreach $pid (@p_s) { my $p_e = 0, $p_t = 0; #for every process pop the first event and examine it if($p_e = pop @{$p_s[$pid]}) { #if process-event has receiver-dependency then push it b +ack on the stack if($receiver{$p_e}) { push (@{$p_s[$pid]},$p_e); } else { my $s_o = 0; #else if process-event has sender-obligation then up +date sender and reciever hashes if($s_o = $sender{$p_e}) { delete $sender{$p_e}; delete $receiver{$s_o}; } #and then enqueue process-event with process-timesta +mp in schedule hash if($p_e =~ m/(\d)-(\d)/) { $p_t = "$timestamp.$1" } else { print "\nerror parsing processor-event signature +\n"; } $schedule{$p_e} = $p_t; unshift (@totalorder, $p_t); } } } $timestamp++; }

Since the timestamp of each event is it's occurance relative to every other event, I don't need any abosolute means of stamping each event, and I can say that my $timestamp < $numevents always. I do need to output the total order of events, as well as each event and it's timestamp, hence I create a third and fourth hash and array respectively, %schedule and @totalorder. I have created a subroutine check_data() that outputs all of the data stored in all of my major data structures, the definition for this is located after all of the code I have in what would be my main() block in C/C++.

Sorry for the lengthy description - anyone here have an idea why the first loop would execute but not the second?

Do I need to initialize my vars prior to use, ex:

$pid = 0; #process index @p_s = (); #2d process array/stack %sender = (); #sending event hash %receiver = (); #receiving event hash $numevents = 0; #total number of events in all processes $timestamp = 0; #timestamp for event scheduler %schedule = (); #hash of each event with timestamp @totalorder = (); #final order of each event

Should be declared before the first loop (I've tried this already w/o success but maybe I'm missing something)?

Will vars declared on the fly in the first loop be visible in the second loop?

I will append the full script at the end of this post for the reference of the more experienced perl-sons who are hopefully perusing this forum...

################### #Lamport.pl ################### #!/usr/bin/perl -w #begin main routine #$pid = 0; #process index #@p_s = (); #process stack #%sender = (); #sending event hash #%receiver = (); #receiving event hash #$numevents = 0; #total number of events in all processes #$timestamp = 0; #timestamp for event scheduler #%schedule = (); #= Tie::IxHash->new(); #@totalorder = (); #read process/event input from file open FILE, $ARGV[0] or die "$ARGV[0] can't be opened:\n$!"; #local $/; # Set input to "slurp" mode. #initialize process/event stack/hash from input file print "\nbegin Lamport's algorithm for input file $ARGV[0]\n"; foreach $line (<FILE>) { chomp $line; if ($line =~ m/(\d)-(\d)->(\d)-(\d)/) { #create local sender and receiver vars my $sp = "$1-$2"; my $rp = "$3-$4"; #update sender and receiver hashes $sender{$sp} = $rp; $receiver{$rp} = $sp; print "enter $sender{$sp}->$receiver{$rp} in dependency hashes +\n"; } elsif($line =~ m/(\d)-(\d)/) { #create local process var my $p = "$1-$2"; #queue process on @p_s multi-dimensional array unshift (@{$p_s[$1]},$p); print "unshift $p_s[$1][0] onto process array\n"; $numevents++; } else { print "\nunmatched line: $line \n"; chomp($line); #remove empty newlines in input file } } print "\ncompleted $ARGV[0] parsing\n"; close FILE; check_data(); #schedule process events according to Lamport's algorithm while($timestamp <= $numevents) { print "\ntimestamp: $timestamp, numevents: $numevents\n"; foreach $pid (@p_s) { my $p_e = 0, $p_t = 0; #for every process pop the first event and examine it if($p_e = pop @{$p_s[$pid]}) { #if process-event has receiver-dependency then push it b +ack on the stack if($receiver{$p_e}) { push (@{$p_s[$pid]},$p_e); } else { my $s_o = 0; #else if process-event has sender-obligation then up +date sender and reciever hashes if($s_o = $sender{$p_e}) { delete $sender{$p_e}; delete $receiver{$s_o}; } #and then enqueue process-event with process-timesta +mp in schedule hash if($p_e =~ m/(\d)-(\d)/) { $p_t = "$timestamp.$1" } else { print "\nerror parsing processor-event signature +\n"; } $schedule{$p_e} = $p_t; unshift (@totalorder, $p_t); } } } $timestamp++; } check_data(); #create "totalorder" copy of schedule hash #pop totalorder as stack and print #sort and print schedule hash #end MAIN routine #begin subroutine definitions sub check_data { #print "numprocs = $numprocs\n"; print "\ntimestamp = $timestamp\n"; print "numevents = $numevents\n"; print "\ncontents of process stack:\n"; foreach my $r (@p_s) { my $j=0; foreach my $c (@{$r}) { print "P$i j: $j Value: $c\n"; $j++; } $i++; print "\n"; } print "\nsender key/value pairs:\n"; foreach my $k (sort keys %sender) { print "$k => $sender{$k}\n"; } print "\nreceiver key/value pairs:\n"; foreach my $k (sort keys %receiver) { print "$k => $receiver{$k}\n"; } print "\nschedule key/value pairs:\n"; foreach my $k (sort keys %schedule) { print "$k => $schedule{$k}\n"; } print "\ncontents of totalorder queue:\n"; foreach my $r (@totalorder) { print "$r, "; } print "\n\n"; }

In reply to simple script question scope/structure for Perl noob by scotchfx

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.