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

I have been working on and, mostly, off on a project the last couple weeks. I am trying to read a list of file names into one array a list of directory contents into another and compare the two outputting any differences. This is my first project with Perl. I'm getting errors on scope (my masks earlier declaration of variable in same scope) and one that says (Useless use of numeric GE (>=) in void context). Any help on this (or any other errors) appreciated.
#!/usr/bin/perl -w use strict; my $boxEnd; my $pathToDirectory; my @contentsOfDataBase; my @contentsOfDirectory; my @copyOfContentsOfDirectory; my @inDirectoryNotInDataBase; print "First Box?"; chomp (my $boxBegining = <>); print "Last Box?"; chomp ($boxEnd = <>); print "Wait a minute while I look... Lazy..."; open dataBaseContents, "+>", "\\\\SHARESERVER\\DigiOfficeShare\\PerlDe +v\\Database.txt" or die "Aww shit I Broke"; @contentsOfDataBase = <dataBaseContents>; while(<dataBaseContents>) { chomp; push(my @contentsOfDataBase, $_); } close(dataBaseContents); while ($boxEnd >= my $boxBegining, $boxBegining++) { my $pathToDirectory = "\\\\SHARESERVER\\DigiOfficeShare\\PerlDev\\Bo +x $boxBegining"; opendir(my $currentDirectory, my $pathToDirectory) || die "You sure +that exists, dummy?"; while(readdir $currentDirectory) { chomp; push(my @contentsOfDirectory, $_); } closedir $currentDirectory; } @copyOfContentsOfDirectory = @contentsOfDirectory; my %seen; $seen{$_}++ for @contentsOfDataBase; $seen{$_} && undef $_ for @contentsOfDirectory; my %seen2; $seen2{$_}++ for @copyOfContentsOfDirectory; $seen2{$_} && undef $_ for @contentsOfDataBase; @contentsOfDirectory = grep { defined } @contentsOfDirectory; @contentsOfDataBase = grep { defined } @contentsOfDataBase; print "These files have PDFs and no database entries: ", @contentsOfDi +rectory, "\n"; print "These files have database entries and no PDFs: ", @contentsOfDa +taBase, "\n";

Original code restored above (in read more block) by GrandFather

</cuse strict; my $boxEnd; my $pathToDirectory; my @contentsOfDataBase; my @contentsOfDirectory; my @copyOfContentsOfDirectory; my @inDirectoryNotInDataBase; print "First Box?"; chomp (my $boxBegining = <>); print "Last Box?"; chomp ($boxEnd = <>); print "Wait a minute while I look... Lazy..."; open dataBaseContents, "+>", "\\\\SHARESERVER\\DigiOfficeShare\\PerlDe +v\\Database.txt" or die "Aww shit I Broke"; while(<dataBaseContents>) { chomp; push(@contentsOfDataBase, $_); } close(dataBaseContents); while ($boxEnd >= $boxBegining) { my $pathToDirectory = "\\\\SHARESERVER\\DigiOfficeShare\\PerlDev\\Bo +x $boxBegining"; $boxBegining++; opendir(my $currentDirectory, $pathToDirectory) || die "You sure tha +t exists, dummy?"; while(readdir $currentDirectory) { chomp; push(@contentsOfDirectory, $_); } closedir $currentDirectory; } @copyOfContentsOfDirectory = @contentsOfDirectory; my %seen; $seen{$_}++ for @contentsOfDataBase; $seen{$_} && undef $_ for @contentsOfDirectory; my %seen2; $seen2{$_}++ for @copyOfContentsOfDirectory; $seen2{$_} && undef $_ for @contentsOfDataBase; @contentsOfDirectory = grep { defined } @contentsOfDirectory; @contentsOfDataBase = grep { defined } @contentsOfDataBase; print "These files have PDFs and no database entries: ", @contentsOfDi +rectory, "\n"; print "These files have database entries and no PDFs: ", @contentsOfDa +taBase, "\n";

Replies are listed 'Best First'.
Re: Question of scope and syntax
by davido (Cardinal) on May 02, 2012 at 18:26 UTC

    There are many inappropriate uses of my in your script. The one that is causing the warning that you're seeing is in line 36, where you say, "open(my $currentDirectory, my $pathToDirecory)...". That one is inappropriate because $pathToDirectory is declared on line 35 already.

    Another inappropriate use is where you say push( my ..., which occurs on lines 25 and 39. The reason that's inappropriate is that every time you try to push, you're declaring a new version of the variable, masking the previous one. Consequently, the variable you're pushing onto will never have more than one element pushed to it, for every push is pushing to a new variable.

    There are so many additional problems it's hard to know where to start. Line 21 slurps a file into an array, and then lines 23-26 try to read from the already exhausted file-handle.

    Line 34 declares $boxBegining within the while loop's conditional, and increments it. That's going to create some wonky and possibly undefined behavior relating to the fact that 'my' has both compiletime and runtime effects. Declare that variable outside of the loop.

    Line 49 should be something more like this:

    @contentsOfDirectory = grep { $seen{$_} } @contentsOfDirectory;

    That would eliminate the need for the grep in line 59. The same goes for line 55 and 60.

    I can't explain the >= issue. But I'll bet if you fix the while loop with a 'my' in the conditional the problem will go away. In fact, it does:

    while ($boxEnd >= $boxBegining++) {

    Dave

Re: Question of scope and syntax
by toolic (Bishop) on May 02, 2012 at 18:04 UTC
    For your 1st warning message, I think you can just change:
    opendir(my $currentDirectory, my $pathToDirectory) || die "You sure +that exists, dummy?";

    to:

    opendir(my $currentDirectory, $pathToDirectory) || die "You sure tha +t exists, dummy?";

    For your 2nd warning, this line is definitely the culprit, but I'm not sure what you're trying to do:

    while ($boxEnd >= my $boxBegining, $boxBegining++) {

    Maybe...

    while ($boxEnd >= $boxBegining) { $boxBegining++;
Re: Question of scope and syntax
by sauoq (Abbot) on May 02, 2012 at 18:05 UTC
    push(my @contentsOfDataBase, $_);

    That's where you are masking an earlier declaration. Just remove the my.

    while ($boxEnd >= my $boxBegining, $boxBegining++)

    And that's where you are using >= in void context. That should probably look something like ...

    my $boxBegining; while ($boxEnd >= $boxBegining) { $boxBegining++; # ... and the rest of your loop ... }
    -sauoq
    "My two cents aren't worth a dime.";
A reply falls below the community's threshold of quality. You may see it by logging in.