Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Marshall's scratchpad

by Marshall (Abbot)
on Dec 26, 2008 at 13:00 UTC ( #732670=scratchpad: print w/replies, xml ) Need Help??

Hi Prinet you have:

-excessive use of global variables
-excessive use of goto - I don't see the need for any.
-weird uses of sleep
-weird uses of splice (a very uncommon function)
much more common is to create a new array with a filter
function. Perl is designed to avoid the use of $i,$j,$k etc.
The use of indicies is very error prone and for the most part,
not needed in Perl.
-always check the result of an opendir or an open file
-your UI could be better expressed as a GUI and Perl can do that.

An example of refactoring your code:

###################################################################### +##### # LOAD RESOURCES + # ###################################################################### +##### if (-d $CurrentDirectory.'/Resources') { opendir (DIRECTORY, $CurrentDirectory.'/Resources'); @Directory = readdir(DIRECTORY); closedir (DIRECTORY); shift(@Directory); shift(@Directory); RemoveDirectories: for ($DirectoryEntry = 0; $DirectoryEntry < @Directory; $Directory +Entry++) { if (-d $Directory[$DirectoryEntry]) { splice(@Directory,$DirectoryEntry,1); goto RemoveDirectories; } } } ################# # this could be a subroutine that gets the simple Resource files # underneath the specified directory # # *** untested *** but the idea is sound.... my @file_paths = get_resource_files ($current_directory); print join ("\n",@file_paths),"\n"; sub get_resource_files { my $directory = shift; opendir (my $fh_resource_dir, "$directory/Resources") or die "$directory/Resources does not exist $!"; # grep is a "filter" function. Only an array of simple file # names are returned. There are things that are not a directory # but are also not a simple file. These are weird, but they exist. # Use the -f test for simple files. # # readdir() only returns simple file names, not the full path # I guess you would really want the full path to the files? my @file_paths = map{"$directory/Resources/$_"} grep {-f "$directory/Resources/$_"} readdir $fh_resource_dir; return @file_paths; # the directory file, handle $fh_resource_dir is automatically # closed when my $fh_resource_dir goes out of scope. # A "barewword" like DIRECTORY has global package scope }
+++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++

Using File::Find

This tutorial shows how to use the File::Find module.

File::Find is a core module, meaning that it is already installed on all Perl systems - no installation is required! If the system has Perl, File::Find is already there!

The find() function is included within that File::Find module. The first step is to tell Perl that you want to use this pre-installed module - that will make the subroutine "find()" known to the rest of the code.

Getting Started:

You need to include a use File::Find; statement at the top of the code, this "imports" the "find" fuction and makes it known to the rest of the code.

What the find() routine does...

The man (manual) page - shown by (perldoc file::find) or via Google search says:
SYNOPSIS:

use File::Find;
find(\&wanted, @directories_to_search);
sub wanted { ... }

I really don't why this "wanted" name got used, but that is a reference to a subroutine name, followed by a list of directory names.

The find() function will cwd (change working directory) into the the first directory in that list and do a readdir(). It will then call the "wanted()" function for every single name from that readdir() list. It might be a directory, it might be a simple file, it might be some kind of linked file/directory (not ususal, but possible).

After find() does that, it will follow the directory names, meaning that it will cwd (change working directory) into the next directory name and continue following it downward calling the "wanted()" function on every "name" whether it be a directory or a simple file or some kind of link.

If we have:

use File::Find; find (\&for_every_name, (C:/temp, C:/Windows); my @allFiles; sub for_every_name { print "$File::Find::name\n"; # note there is no "return value" # it is not possible to return anything from this # subroutine # If you want that: push @allFiles, $File::Find::name; # you must save information in a varialble that has higher # scope than this subroutine # There is NO return value from this subroutine! }
The above will print the names of all files (and directories and symbolic links) underneath C:/temp and C:/WINDOWS (NOTE: Windows file systems are case insensitive, but Unix file systems are case sensitive - so be aware of that!).

Special Variables

Within the subroutine that the find() routine calls, a couple of special variables to tell you where it is "at":

-$File::Find::name - the name of the file that the "wanted()" function is currently looking at.

-$File::Find:dir - the name of the current directoryt that the wanted() function is currently within.

Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2017-09-23 17:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (273 votes). Check out past polls.

    Notices?