On Friday 09 April 2004 10:54, you wrote: > Hi, > > I'm trying to create a perl program that will recurse into > > subdirectories. I have: > > sub scandir { > > local $dirname=shift; > >
You should use "my $dirname = shift;" instead of "local" here. It's safer. > > opendir DIR, $dirname or die "Couldn't open ${dirname}: $!\n"; > > Just for safeness, it would be better if you localize DIR here: <<< local (*DIR); opendir DIR... >>> > > local $direntry; Again - my $direntry; > > while( $direntry=readdir(DIR) ) { Instead of using readdir in a loop, I strongly recommend that you read all the entries into an array and then loop on it: my @entries = readdir(DIR); closedir(DIR); foreach $direntry (@entries) { .. } Otherwise, many dirhandles will be opened, and I'm not sure if the results will be very expectful. (with local and all) > > if( $direntry!~/^\./ ) { Do you want to avoid only "." and ".." or any directory that starts with "."? Your code does the latter. > > local @state=stat($dirname.$direntry); > > print "$dirname$direntry $state[2]\n"; > > if( (($state[2] & ~7777)>>12) ==4 ) { # A directory - recurse This can be simplified into: <<< if (-d $dirname.$direntry). { # A directory - recurse >>> "-d" is a file check that checks if a file is a directory. Check "perldoc -f -X" for more information. > > scandir($dirname.$direntry."/"); This is good. Albeit many people like to use interpolation: scandir("$dirname$direntry/"); > > } > > } > > } > > > > closedir DIR; > > } > > 1. I know, I write perl like a C programmer, I can't help it. Feel free > to show me how it's done. :-) > 2. For some strange reason, the moment I recurse once, the entire loop > structure exits. I suspect it's because the DIR handle is global. Will > any perl guru comment on how it's supposed to be done? If you "local"ize *DIR, it won't happen. > 3. What the @$([EMAIL PROTECTED] is the difference between "my" and "local"? Which > one should I use here? > "my" declares a lexically-scoped variable. It is similar to (define) in Scheme. The value of this variable is not propagated to subsequent function calls (unless they are closures). So for example: <<< #!/usr/bin/perl -w use strict; my $myvar = 3; sub my_called_function { print "In called: \$myvar = $myvar\n"; $myvar = 10; } sub my_caller_function { my $myvar; $myvar = 500; my_called_function(); print "In caller: \$myvar = $myvar\n"; } my_caller_function(); print "In Global: \$myvar = $myvar\n"; >>> will print: <<< In called: $myvar = 3 In caller: $myvar = 500 In Global: $myvar = 10 >>> "local" creates a dynmically scoped localization. The value of the variable is recorded when the local is encountered, and restored once the block exits. It is propogated to all subsequent function calls. So for example: <<< #!/usr/bin/perl -w $myvar = 3; sub my_called_function { print "In called: \$myvar = $myvar\n"; $myvar = 10; } sub my_caller_function { local $myvar; $myvar = 500; my_called_function(); print "In caller: \$myvar = $myvar\n"; } my_caller_function(); print "In Global: \$myvar = $myvar\n"; >>> prints: <<< In called: $myvar = 500 In caller: $myvar = 10 In Global: $myvar = 3 >>> Generally, "my" should be used for all regular variables (scalars, arrays and hashes) because it's safer, while "local" should be used for filehandles, and built-in variables. (the ones in "perldoc perlvar") This is because they cannot be effectively scoped with my. Hope it helps. There's more information about it on the Web and in the Perl documentation. As others noted, you can use the "File::Find" Perl module to traverse a directory tree. Regards, Shlomi Fish -- --------------------------------------------------------------------- Shlomi Fish [EMAIL PROTECTED] Homepage: http://shlomif.il.eu.org/ Quidquid latine dictum sit, altum viditur. [Whatever is said in Latin sounds profound.] ================================================================= To unsubscribe, send mail to [EMAIL PROTECTED] with the word "unsubscribe" in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]