Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Question of scope and syntax

by Hellhound4 (Novice)
on May 02, 2012 at 17:33 UTC ( #968493=perlquestion: print w/ replies, xml ) Need Help??
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";

Comment on Question of scope and syntax
Select or Download Code
Re: Question of scope and syntax
by toolic (Chancellor) 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.";
Re: Question of scope and syntax
by davido (Archbishop) 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 Hellhound4 (Novice) on May 02, 2012 at 19:54 UTC
    I updated my code in the original post. The issue now is that it doesn't seem to be storing values in the arrays. The program is intended to output values only found in one array not in both and should output 2 files, one for each. It doesn't print anything.
      I updated my code in the original post.

      Err... you shouldn't do that. It kind of kills the context for all the answers that you get. These nodes stick around. Say someone finds your question a year from now and starts looking at the replies and they don't match the code in your post? All it'll do is confuse them.

      You can always post new code in a reply. Or just post another question. But before you do, how about not being so quick to give up on figuring it out yourself? You won't really learn anything by continually asking how to fix this or that and just sort of pasting the solutions in. Take a few hours to try to learn at least the basics of the language you are using.

      Is this your first attempt at programming altogether?

      -sauoq
      "My two cents aren't worth a dime.";

      Well, that's definitely progress, and your code looks a lot better, though I recommend re-reading and understanding the latter portion of my previous post so that you can re-work your greps.

      But back to your modified problem: If your code now runs, but just doesn't output what you're expecting it to, it's time to pull out the age-old debugging tool: print. Pepper your code with print statements that output the current state of various variables, which logic paths you followed, and when you're inside of loops... that sort of thing. The actual Perl debugger could be helpful, but it's harder to learn. For a short script like yours, the shortest learning curve is to just sprinkle print statements all over the place.

      The idea is to look at a line of your code and think up an assertion: "I believe that before this line @something contains X, and after this line of code, @something contains that." Now put a print statement before and after demonstrating that assertion, as well as whatever variables contribute to creating the change. Run your code. Watch your assertions do what you expect, or fail. When they fail, hopefully the print statements will give you enough of a clue regarding the failure that you can figure out why it's failing.


      Dave

        I followed your advice. I have narrowed my problem down to the comparison part of my code here:
        foreach (@contentsOfDataBase){ chomp ($_); print "$_"; @inDirectoryNotInDataBase = grep {!"$_"} @contentsOfDirectory; print "@inDirectoryNotInDataBase", "\n"; } foreach (@copyOfContentsOfDirectory){ print "$_"; @pdfNoMatchingDirectory = grep (!$_, @contentsOfDataBase); print "@pdfNoMatchingDirectory", "\n"; }
        They're nearly identical so it is the same problem in both. I changed the structure of the grep function to see if that would fix it. It didn't. The problem specifically lies in the grep line itself. This is how I understand that block to work.
        foreach (@contentsOfDataBase){ chomp ($_); print "$_"; @inDirectoryNotInDataBase = grep {!"$_"} @contentsOfDirectory; print "@inDirectoryNotInDataBase", "\n"; } foreach (@copyOfContentsOfDirectory){ print "$_"; @pdfNoMatchingDirectory = grep (!$_, @contentsOfDataBase);#for curre +nt element in @copyOfContentsOfDirectory find all elements of @conten +tsOfDataBase that are not a match print "@pdfNoMatchingDirectory", "\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://968493]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (18)
As of 2014-08-27 13:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (238 votes), past polls