Another perl coding challenge

Bobby Kleemann rkleeman at neta.com
Wed Jan 3 16:59:59 CST 2001


~sdpm~
On Thu, Dec 28, 2000 at 06:59:02PM -0800, Todd Rockhold wrote:
> ~sdpm~
> Probably not as fun as Garrett's "reversible NAND gate" problem, but here is
> one I have encountered. I have a test system (Perl 5.6) and a production
> system (Perl 5.005).  I would like to run the tree walker on the production
> system.
> 
> The following code walks  a directory tree if run with Perl 5.6 but fails
> with earlier versions.  How do I modify it so that it will work with Perl
> 5.005?
> 
> ----------------------------------------------------------------------------
> --------------------------------------------------------------
> 
> my $DIR = "//yogi/yogidata/OntoCHROMRun/TestRuns";  # contains well files
> my $it = make_treewalker($DIR, \&is_well_file, sub {@{$_[1]}});
> while (defined (my $f_it=$it->()))  
> {
>    # process the interesting file
>    print "found file: $f_it\n";
> }

Try adding this here

sub rand_str {
	my $str = '';
	for (my $i = 0; $i < 8; $i++) {
		$str .= ('A' .. 'Z', 'a' .. 'z', '_', '0' .. '9')[rand 63];
	}
	return $str;
}

> 
> sub make_treewalker    #black magic to walk the directory tree
>    {
>      my @queue = shift();
>      my ($is_interesting, $userparam) = @_;
>      return sub
>        {
>  	while(1)
>  	  {
>  	    return undef unless @queue;
>  	    my $cur = shift @queue;

And change this line

>  	    if (-d $cur && opendir my $dh, $cur)

To this instead

my $dh = rand_str;
if (-d $cur && opendir $dh, $cur)

>  	      {
>  		my @files = grep {$_ ne '.' && $_ ne '..'} (readdir $dh);
> 		push @queue, map {"$cur/$_"} @files;
>  	      }
>  	    return $cur if $is_interesting->($cur, $userparam);
>  	  }
>        }
>    }
> 
> 
> sub is_well_file # what files do we care about?
>   {
>     return () unless -f $_[0] && -T $_[0];  # gotta be a simple file
>     return () unless open FH, "< $_[0]";    # gotta be able to open it
>     return ($_[0]) if $_[0] =~ /\.wel/i ;   # gotta be a .WEL file
>     return ();                              
>   }

If you change the order of these test it will run a little bit faster.  
Since you already know the name of the file you can test the .wel
extension quickly and easily (should the test really be /\.wel$/i meaning
that .wel has to be at the end rather than just somewhere inside there?).  
The open test is taken care of with the -T (-T works by reading the first
block of the file and seeing if it's contents are in the ascii printable
range). Try this:

sub is_well_file # what files do we care about?
{
	return unless $_[0] =~ /\.wel$/i;
	return unless -f $_[0] && -T _;
	return $_[0];
}

 _ _ _
 Bobby Kleemann <rkleeman at neta.com>
 http://www.neta.com/~rkleeman/


~sdpm~

The posting address is: san-diego-pm-list at hfb.pm.org

List requests should be sent to: majordomo at hfb.pm.org

If you ever want to remove yourself from this mailing list,
you can send mail to <majordomo at happyfunball.pm.org> with the following
command in the body of your email message:

    unsubscribe san-diego-pm-list

If you ever need to get in contact with the owner of the list,
(if you have trouble unsubscribing, or have questions about the
list itself) send email to <owner-san-diego-pm-list at happyfunball.pm.org> .
This is the general rule for most mailing lists when you need
to contact a human.




More information about the San-Diego-pm mailing list