Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Strange behavior in File::Find (stopped working for no reason)

by pvaldes (Chaplain)
on Apr 12, 2021 at 16:40 UTC ( [id://11131149] : perlquestion . print w/replies, xml ) Need Help??

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

I'm perplexed. Can you tell me what is wrong with this script?

#!/usr/bin/perl -w use strict; use warnings; use diagnostics; use File::Find; open (my $t, '>', '/home/myuser/myfilename.sql') or die $!; print $t "blah blah\n"; find( { preprocess => \&hi, wanted => \&work, postprocess => \&bye, fo +llow_skip => 1 }, "."); sub hi { print $t "hi\n"; return;} # works correctly sub bye { print $t "bye\n"; return;} # works correctly sub work { print "my name is: ", $File::Find::name; print $t "I'm a file!"; return;} close $t;

when I run the script in the current tree directory I would expect a list of filenames being printed in screen and a text file containing:

blah blah hi I'm a file!I'm a file!I'm a file!... etc bye

But what I have is: "my name is: ." or "my name is: 1" and a file containing:

blah blah hi bye I'm a file! <-yep, solitary and in the wrong position

libfile-find-wanted-perl/testing,testing,now 1.00-1.1 all installed, automatic

Can somebody tell me what is happening here? Is not a little late for an 1-April Joke?

Replies are listed 'Best First'.
Re: Strange behavior in File::Find (stopped working for no reason)
by choroba (Cardinal) on Apr 12, 2021 at 16:58 UTC
    Let's read the documentation.

    > "preprocess"
    The value should be a code reference. This code reference is used to preprocess the current directory. The name of the currently processed directory is in $File::Find::dir. Your preprocessing function is called after "readdir()", but before the loop that calls the "wanted()" function. It is called with a list of strings (actually file/directory names) and is expected to return a list of strings. The code can be used to sort the file/directory names alphabetically, numerically, or to filter out directory entries based on their name alone. When follow or follow_fast are in effect, "preprocess" is a no-op.

    Your preprocess subroutine, hi, returns an empty list, so there are no files too iterate over.

    Why wasn't the preprocess subroutine called before wanted? Because the directory argument to find() is not preprocessed, wanted is run on it directly. Only the directories' contents that are subject to readdir are preprocessed.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Thanks Choroba. Solved. Now I need to put a nice glob in &hi and... voila! That solves my main problem with the real script

Re: Strange behavior in File::Find (stopped working for no reason)
by pvaldes (Chaplain) on Apr 12, 2021 at 16:58 UTC

    Ok, I will autoreply me. Is the preprocess routine that replaces the whole list of files by just "1" when returns correctly, Right?

    Yep, tested, that stupid thing again. After quoting the sub hi part it works like a charm