in reply to cant open files from a directory

G'day garny,

Welcome to the monastery.

The following repeats some of the information you've already been given. I've expanded on most of this because you say "I am a noob to perl" and you might as well get into good habits from the outset.

'die "cannot open"' and 'die"oops"' are poor error messages that convey little information. I find the autodie pragma is the easiest option; however, if you wish to hand-craft your error messages, do so in a useful fashion (e.g. 'die "Can't open $file for reading: $!"').

Unless you have a good reason not to, use lexical filehandles and directoryhandles (see examples in open and readdir respectively). Package variables (e.g. D and MYFILE in your posted code) are slower to access than lexical variables and you can't control their scope the way you can with lexical variables: in a tiny script, such as you have here, those reasons probably won't matter much, if at all; when you start writing more complex code, you may find this will save you debugging headaches (a good reason to avoid package variables even if the speed factor is negligible).

Get into the habit of using the 3-argument form of open: the documentation has details.

Close handles when you've finished with them; don't leave this until the end of your script. In the code your posted, the closedir() statement could have been placed immedaitely after the readdir() statement.

As explained in the readdir documentation, this function returns directory entries. While this will include the types of files you're intending to read (source code, config files, etc.), it will also include directories (at least the current, '.', and parent '..', directories) as well as symbolic links, character and block special files and so on: you can use the file test operators to filter the type(s) you want.

Instead of using

my @files = readdir($dirhandle);

which returns just the names of all the files, directories, etc., you can use

my @files = grep { -f } map { "$dir/$_" } readdir($dirhandle);

which returns the pathnames of just the files you want.

[Also consider File::Spec for a more portable solution for "$dir/$_".]

-- Ken

Replies are listed 'Best First'.
Re^2: cant open files from a directory
by Anonymous Monk on Feb 01, 2014 at 05:38 UTC
    my @files = grep { -f } map { "$dir/$_" } readdir($dirhandle);

    To combat the excessive grepping & mapping going on above ...

    my @files = map { -f $_ ?"$dir/$_" : () } readdir( $dirhandle ) ;

      I'd hardly consider one grep and one map to be "excessive grepping & mapping" nor something that one would need to "combat".

      However, should you prefer the style you've posted, "-f $_" suffers from the problem already pointed out four times in this thread.

      You could employ excessive usage of "$dir/$_", though. :-)

      -- Ken

        Blocks of grep & map were simple enough, which could have been combined simply, notwithstanding my lack of attention to ...

        Thanks for pointing out the bug the fifth time that I had missed in my zeal to curb the extravagance.

        I would rather have then map { $f = "$dir/$_" ; -f $f ? ... } ..., though some may find "$f" to be excessive. (By this time I would have busted out File::Find already to be honest.)