I am starting to write perl code again for my job and have been just messing around with OO programming to refresh my memory (it's been almost 5 years since I've done any serious perl programming). Anyhow, I wrote a couple classes one of which when instantiated takes a reference to an array in my calling script.

The application simulates a shepherd locating 100 sheep in an an area 500x500. When the sheep objects are created, they are given random x,y coordinates and pushed on to the array. Then I instantiate my Field object and pass a reference to the sheep array. Then I instantiate my Shepherd object passing a reference to the Field object.

The shepherd then, in a loop looks around to find the closest sheep to him and goes and collects it. When he finds it, he removes that sheep from the original array. The issue is that I am using the splice command to remove the sheep, but the number of sheep before the splice is 100 and after is 99, but then on the next iteration of the loop where the shepherd locates the next closest sheep, he goes to remove the sheep from the original array which is showing 100 sheep again even though I removed (or thought I did) the sheep from the last iteration.

Maybe there's just a logic issue I'm missing here, but I can't figure out why my array seems to get reset to 100 each time and then after the splice is 99. It seems that the array is a copy and not the original. I checked the references and they appear to have the exact same address as the original array. Anyhow, it's probably simple, but I can't seem to get it. Here's the RemoveSheep method inside of my Shepherd object:
sub RemoveSheep { my $self = shift; my $obj = shift; # This is the sheep object my $field = ${$self->{field}}; my @sheep = @{$field->Sheep}; my $index = 0; my $found = undef; foreach my $sheep (@sheep) { if( $sheep == $obj ) { $found = $index; last; } $index++; } if( defined($found) ) { my $sheep = $sheep[$found]; print "Before Splice: " . @sheep . "\n"; splice (@sheep, $found, 1); print "After Splice: " . @sheep . "\n"; } }

And here is the calling script:
#!/usr/bin/perl -w use strict; use Sheep; use Shepherd; use Field; my $fieldWidth = 500; my $fieldHeight = 500; my @sheep = (); for(my $i = 0; $i < 100; ++$i) { my $randX = sprintf( "%d", rand($fieldWidth)); my $randY = sprintf( "%d", rand($fieldHeight)); my $sheep = new Sheep($randX, $randY); push(@sheep, $sheep); } print "Address of array is: " . \@sheep . "\n"; print "Shepherd now looking for " . @sheep . " sheep\n"; my $field = new Field( $fieldWidth, $fieldHeight, \@sheep); print "Shepherd starting at: 200:300\n"; my $shepherd = new Shepherd(\$field, 200, 300); $shepherd->FindSheep();

In reply to Array Reference Issue by mlong

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.