while i agree that it is probably a good idea to use someone else's wheel, it is often helpful to figure out what's wrong with the round thing you thought you were building. since no-one else spoke of your spokes, i stuck a stick in them myself, and i think i have it.

i think most of your problem is in this section:

a: for(@infiles) { b: $_ =~ s/^(\.|\.\.)$//; c: if (-d $_) {
at line a, you are implicitly setting $_ to items from the directory $dir. in line b, you throw out . and .., and in line c you test to see if $_ is a directory. however, $_ is, in all these cases, relative to $dir -- and perl has no way of knowing that. -d needs the full path or, i believe, the path relative to the location of the script that's running. so here's a quick re-write that will fix this:

#!/usr/bin/perl -w use strict; my @dirs = ( # omit trailing slash '/var/www', '/home/me', '/usr/games', ); for my $dir (@dirs) { opendir DIR, $dir or warn "Error opening $dir:\n$!"; my @infiles = (readdir DIR) or warn "Error reading $dir:\n$!"; closedir DIR or warn "Error closing $dir:\n$!"; for(@infiles) { $_ =~ m/^\.{1,2}$/ and next; my $d = "$dir/$_"; if (-d $d) { push @dirs, $d; next; } # do stuff } } for(@dirs) { print " $_\n"; }

some notes:

first, though this treatment of the array works, i don't like it. manipulating the array you're looping on is vaguely dangerous, just because you get tempted to do much worse things than push onto the end of it. i'd replace that with a while ($dir = shift @dirs), and push $dir onto @keep if you need to keep them for later.

second, you'll note i changed your regex line. i made two changes, both possibly minor stylistic things. one was use of the {1,2} to indicate "one or two" because i find that easier to read than the multiple backslashes and alternation. two, rather than turning those into blank entries and keeping them, if it matched that, i next. why? a little lower, i generate an absolute path by appending the local dirname ($_) onto my current "base" path ($dir), with a slash. if i kept blank ones, this would add the base path back in twice -- infintitely filling the array. ew. bad.

i'd also recommend not using $_; you're naming it explicitly anyway, you might as well give it a real name. but that's totally my own bias, so ignore that.

.

anyway, the moral of the story is "use those other modules" -- but the other lesson is "perl can't guess what you're thinking more than about 90% of the time."

.

In reply to Re: Read directories' contents, add subdirs back into directory list by Vynce
in thread Read directories' contents, add subdirs back into directory list by ybiC

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.