Click to See Complete Forum and Search --> : Directory Handle, static object and recursive functions
yitzle
03-07-2007, 11:00 PM
I'm gonna be posting my script, so before I do, I hereby release any code in the post under the MIT license (http://www.ecf.utoronto.ca/~goodi/html/software.html).
Script now at http://www.ecf.utoronto.ca/~goodi/html/scripts/thumbnail_creator.pl
The script recursively explores a file tree, creating a copy of the directory structure and converts any .jpg files found in it the source tree to a thumbnail in the destination tree.
43 lines or so. Pretty straight forward.
Unfortunately, when I last tried running it, it didn't explore the entire tree. HELP! Why not? When you got a recursive function can you declare a DIR_HANDLE in it? Do the DIR_HANDLE's affect each other?
dragle
03-08-2007, 03:18 PM
Hi,
As is your script doesn't cover the whole tree because you are specifically filtering out any directory entries that don't end in .jpg or .jpeg. I.E., you're throwing away both files and directories that don't end in one of those two suffixes; thus you don't crawl down into directories that don't match that construct.
But to answer your question more directly, yes; regular directory handles are treated as package globals in a similar manner to filehandles (though filehandles and directory handles have different namespaces) so they survive calls to another function. There are many ways to get around this; but if you have Perl 5.6 or later probably the easiest is to just use:
opendir my ($dh), '/home/dragle';
foreach (readdir $dh) {
print $_, "\n";
}
closedir $dh;
When you do it that way, $dh is scoped to the block you're using it in, as it appears you are expecting.
Technically, what you have should work; though probably not for the reason you think. Each time you call opendir on a handle that's already open, Perl just closes the old handle and reopens it with the new directory; and since you're processing the readdir in a list context
foreach (readdir(DIR)) {
then your script already has the full directory listing that it needs before it calls the function recursively (i.e., before the next opendir comes along and closes the first directory listing). So you continue looping through the original directory's listing even though the directory handle has been closed. But the above approach (IMO) is much cleaner and on point with what you want.
Good luck!
yitzle
03-08-2007, 03:40 PM
Thanks. I found of Perl Monks site that a method used is to read the data into a local array and use the array for looping.