Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Re: Help with $File:Find

by Marshall (Abbot)
on Feb 14, 2018 at 20:06 UTC ( #1209177=note: print w/replies, xml ) Need Help??

in reply to Help with $File:Find

Your code for sub get_files looks a bit odd to me. The reason being that @array is not accessible after the find() operation. Normally you have to declare @array at the same scope as find(). Also, there actually isn't a need for sub nodirs{}. You could just have a next if (-d $File::Find::name); in the get_files{} sub. I am a bit flummoxed as to how $_ could wind up being undef because this is a file name like readdir() would return. Show us what $TYPES is? There could be something odd in the regex, often \Q$TYPES\E is needed.

A a debug thought, I would add: print "looking at $_\n"; in your get_files routine. I would be astounded if that specific line shows an attempt to print an undef value error.

Replies are listed 'Best First'.
Re^2: Help with $File:Find
by roperl (Beadle) on Feb 14, 2018 at 21:24 UTC
    There is more to my get_files sub that does a foreach (@array) and then checks the files for certain criteria.
    I left out that section for clarity here.
    My $TYPES is defined like so:
    my $TYPES = 'txt|gz|zip';

    The only thing I can think of is that the find could be finding a number of files in a directory first and then filling in the names and so if the file is gone in the middle of the operation $File::Find::name will fail because the file name isn't defined.
      I and other Monks aren't sure what is happening here. Let's get more info:

      Add the line $|=1; at the top of your program. This will unbuffer STDOUT. Then put in some print statements as I suggested earlier. Then when the error happens, we will have an idea of what the program was doing. By default, STDOUT is buffered meaning that it only prints when its line buffer is full. STDERR is non-buffered by default meaning that it's error lines print right away. When you un-buffer STDOUT, the time sequence of the normal prints and error prints are preserved. The line right before the error will show what the program was doing right before the error occured.

      Update: you said "There is more to my get_files sub that does a foreach (@array) and then checks the files for certain criteria. I left out that section for clarity here." It could very well be that your simplification obscures the actual problem. Can you reproduce the problem with your simplified code?

        I can't seem to reproduce the problem. It doesn't happen very often. This program runs a daemon and only occurred once in 2 weeks. I'm pretty certain it's not after the $File::Find::name as when the error occurs it references the line where push @array, $File::Find::name is. Here is my actual code.
        find( { wanted => \&get_files, preprocess => \&nodirs }, "$BASEDIR +/$dir" ); sub nodirs { grep !-d, @_; } sub get_files { my @array; push @array, $File::Find::name if ( (/^(?!\.).*\.($INTYPES)$/i +) || ( (/^(?!\.).*\.($INTYPES)\.($ENGZTYPES)$/i) && !(/\.($OUTTYPES)\ +.($ENGZTYPES)$/i) ) ); foreach (@array) { if ( ( exists( $globalfiles{$_} ) ) && ( ( $globalfiles{$_ +} ne 'submitted' ) || ( $globalfiles{$_} ne 'working' ) ) ) { next; } else { if ( -e $_ ) { my $lckfile = getlckfile($_); if ( -e $lckfile ) { next; } push @tmparray, $_; } } } }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1209177]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2018-03-21 23:07 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (272 votes). Check out past polls.