Re: Recursive sub
by dragonchild (Archbishop) on Sep 23, 2003 at 17:58 UTC
|
First - if you're doing this for a learning exercise, that's fine. But, using File::Find is NOT "stealing code". It is using well-tested and well-written solutions to common problems. I hope you wouldn't think you'd have to rewrite CGI, DBI, or XML::Parser because you'd be "stealing code".
That said, you have a few "issues" with your code. Try the following:
use File::Spec;
my $dir = "C:\";
sub recurseDir2
{
foreach (glob shift)
{
if (-d)
{
print "Directory: '$_'\n" ;
recurseDir2(File::Spec->catfile($_, '*'));
next;
}
if (-f)
{
print "File: '$_'\n";
}
}
}
recurseDir2($dir)
I wasn't able to reproduce your problem, but I think I know where it might have come from. You're on a Windows system, but using the Unix directory syntax. This is why modules exist, to make sure you don't get screwed up. File::Spec will make sure you use the right directory separator for your system. This isn't "stealing code" - this is intelligent re-use of well-thought out solutions.
------ We are the carpenters and bricklayers of the Information Age. The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6 Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified. | [reply] [d/l] |
|
|
Thanks dragonchild, I am aware that I am not stealing code. I was just making the point that I don't want to just cut and paste code that I don't understand. For me to learn Perl I need to be able to write my own code so that I get a full understanding.
I hadn't seen the File::Spec module, I will read up on it.
In your code you are short forming
foreach (glob shift)
I assume by not supplying the array. Is this the case?
This is one area that I am having difficutly in reading other peoples code at this point, Perl makes allot of assumptions that I am not aware of yet, or just don't remember at this point.
Paul Neale
| [reply] [d/l] |
|
|
There are not many that I can help because of my relative new-ness to perl! But you seem willing to put forth the effort, and I can answer some of your questions. Well, I would like to suggest you pick up a copy of Learning Perl 3rd Ed Written by our very own Merlyn. Trust me, you will learn a lot from it.
In the line foreach (glob shift) Perl is using @_ as it's default.
LR
Whip me, Beat me, Make me use Y-ModemG.
| [reply] [d/l] [select] |
Re: Recursive sub
by BrowserUk (Patriarch) on Sep 23, 2003 at 18:26 UTC
|
P:\test>perl -c -mstrict -w junk.pl
Scalar value @_[0] better written as $_[0] at junk.pl line 6.
syntax error at junk.pl line 5, near "sub recurseDir2 "
Can't use global @_ in "my" at junk.pl line 6, near "glob @_"
syntax error at junk.pl line 17, near "}"
junk.pl had compilation errors.
If you correct the missing semicolon on the first line, the use of @_[0] instead of $_[0] in the third and the ommission of the '2' in the subname in the 7th line, it appears to work fine.
Adding -w and use strict isn't obligatory, but it would probably have saved your need to post this question.
#! perl -w
use strict;
my $dir = "C:/";
sub recurseDir2 {
my @temp = (glob $_[0]);
foreach (@temp) {
if (-d $_) {
print "Directory: $_" , "\n" ;
recurseDir2("$_/*");
}else{
if (-f $_) {
print "File: $_ \n";
}
}
}
}
recurseDir2($dir)
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
It's often called the shebang line, and is mostly used on unix systems to tell the shell where it should look for the perl binary. Windows doesn't use this mechanism to find the binary, so that use is mute.
However, if the line is present, perl will inspect it and respect (some of) the runtime switches (see Perlrun).
I use it as a "reminder" for switches that I have permenantly enabled through the assoc/ftype mechanism (-sw) --mostly so people can see what I use when I post code.
I also use it to enabled individual switches on a case by case basis. The most frequent one being -l as it save me having to add "\n" to the end of every print line. Of course, there are times when you don't want a newline printed, in which case I just use printf $string; instead. Works for me:)
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.
| [reply] [d/l] |
|
|
I just tried use strict and it stops everything from printing. Should this happen?
Paul Neale
| [reply] |
|
|
No. use strict; shouldn't stop everything from printing...and it doesn't on my system.
I suspect that you are running your script from the Explorer by double clicking and the reason you see no output is because you have a compilation error that prevents your script reaching the sleep statement and so the window is disappearing before you have a chance to read the error messages produced.
I would advise you to start using the command line, at least for testing your scripts.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.
| [reply] [d/l] |
|
|
Re: Recursive sub
by Not_a_Number (Prior) on Sep 23, 2003 at 19:30 UTC
|
A couple of remarks on top of those of BrowserUK:
1) Perl has an elsif option, so you can simplify you sub thusly:
sub recurseDir2 {
my @temp = (glob $_[0]);
foreach (@temp) {
if (-d $_) {
print "Directory: $_" , "\n" ;
recurseDir2("$_/*");
}
elsif (-f $_) {
print "File: $_ \n";
}
}
}
2) There might (I'm not sure with Windoze) be some 'things' in your directories meet neither the -f nor the -d test. In which case, I would recommend adding an else clause:
sub recurseDir2 {
my @temp = (glob $_[0]);
foreach (@temp) {
if (-d $_) {
print "Directory: $_" , "\n" ;
recurseDir2("$_/*");
}
elsif (-f $_) {
print "File: $_ \n";
}
else {
next;
}
}
}
hth
dave | [reply] [d/l] [select] |
|
|
Your else clause is unnecessary, as it's not doing anything. There definitely will be stuff (in many directories) that don't meet the -f or -d tests. In that case, he will just fall through and the loop will continue with the next item.
------ We are the carpenters and bricklayers of the Information Age. The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6 Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.
| [reply] |
|
|
my @anomalies;
sub recurseDir2 {
my @temp = (glob $_[0]);
foreach (@temp) {
if (-d $_) {
print "Directory: $_" , "\n" ;
recurseDir2("$_/*");
}
elsif (-f $_) {
print "File: $_ \n";
}
else {
push @anomalies, $_;
}
}
}
print "Anomalies: @anomalies";
but as I found no 'anomalies' in my filepaths I stupidly changed my code to what I posted. Thanks for pointing out my mistake.
dave | [reply] [d/l] |
|
|
sub recurseDir2 {
opendir(DIR, $_[0]);
my @temp = readdir(DIR);
closedir DIR;
#my @temp = (glob $_[0]);
foreach (@temp) {
if (-d $_) {
print "Directory: $_" , "\n" ;
recurseDir2("$_/*");
}
elsif (-f $_) {
print "File: $_ \n";
}else{
print "Other: $_ \n";
}
}
}
recurseDir2('c:/');
---8<---
Other: deleteme.htm
Other: I386
Other: DISCOVER
Other: AUTOEXEC.BAT
Other: CONFIG.SYS
Other: deleteme.gif
Other: BOOTLOG.TXT
Other: WINDOWS
Other: casa_gms.zip
Other: Answer.txt
Other: Recycled
Other: sacoss_crm.zip
Other: convert_rarossa.zip
Other: mpcsetup.log
File: console.zip
Directory: data
---8<---
because windows folders usually don't have extensions and files usually do have extensions this concept could be used in a controlled environment to recurse through all folders (things with no extension)
___
/\__\ "What is the world coming to?"
\/__/ www.wolispace.com
| [reply] [d/l] [select] |