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


Fellow Monks,

Due to recent prodding by lestrrat i decided to take up some code i had been writing that solves the nqueens problem. Eventually this code will get a Tk interface (hopefully using the nifty new module from clintp) and become a screensaver. The algorithms that do the behind the scenes stuff are almost done, and when implementing the last major optimization i ran into a brick wall.

This is implemented using OOP and i decided that it would make the most sense to have the chessboard and the queens be objects. The recent optimization involved moving some code that checks all the contested values for all the queens from main into Board.pm; now i run this code once directly after set-up, as opposed to in between every queen swap (there's a new code snippet in main to deal with changed contested values that runs in O(N) time :). In main it worked fine, but in Board.pm it fails in one interesting way. contested is a method in Queen.pm defined as thus:

sub contested : lvalue { my $self = shift; $self->{_contested} }
And that has proven to work fine. When the code to determine contentions was in main all of the values got updated appropriately. Now that i have moved this to Board though i have found that it will get the value for contested, but not set it.

When going through Board.pm to find out why i ran into another interesting quandery; i had not required the Queen object in Board, yet it made new Queens, changed their location and other things anyway. The require line has since been added to Board.pm (and i smacked myself for forgetting it) but it did not fix any problems. So, with that set up, here is my snippet for setting the number of contentions (for reference) quickly followed by my questions:

# works in package main; but not package Board; foreach my $queen1 (@queens) { LOOP: foreach my $queen2 (@queens) { next LOOP if $queen1->duplicate($queen2->location); $queen1->contested++ if $linear->($queen1->location, $queen2->lo +cation); } }
  1. Does Perl not need require statements on module A inside of module B if module A is required in main before module B? If so i think this is probably a misfeature
  2. Is there another way to explain why i didn't need to require the Queen module in Board.pm and still got to use all of it's features?
  3. Most importantly, why can i not set the lvalue correctly? For example:
    $queen1->contested++
    no longer works, when it worked (and works) fine in the main package.
Thanx for any help,
jynx

Replies are listed 'Best First'.
Useful info...
by jynx (Priest) on Nov 19, 2001 at 04:43 UTC

    D'oh! Forget me own head next,

    i should mention that i'm using perl5.6.0 on a redhat linux box. Also, i did at least 5 or 6 tests trying to get lvalue to work properly, and they didn't work. So when i put in the require line i obviously forget to test extensively. The lvalue problem was fixed by adding the require line, but that still doesn't explain the source of the problems, questions 1 & 2.

    jynx

    UpdateAha! Further testing shows that the lvalues don't get set properly when run with perl -d, but do get set properly without it! Wait... what? Can someone please explain?