sabato 29 aprile 2017

Another baby Perl program from a backup in the attic

This is a simple script that takes all arguments on the command line and returns a list of directories for each argument.
I don't remember at all what the purpose of this was, probably something to process a set of directories via a batch starting from
a set of filenames.
By the way, let's say how baby I was at that time…


1.1 Baby Code

Here it is, please note how long the code is…



#!/usr/bin/perl

# This script manipulates all its arguments returning a list of string which
# are the directory of all files. For example if the argument is
# /home/luca/file.txt only /home/luca/ is returned (note the last backslash).


# return array
@ret;

foreach $name (@ARGV){


    if( -f $name ){

 # check if the name contains a /, if no the directory must be the current one (./)
 if(not  $name =~ /\// ){
     $ret[++$#ret] = "./";
 }
 else{

     @parts;
     $dir;

     # split into the section with /
     @parts = split("/",$name);


     if( defined(@parts) ){

  for($i=0; $i < $#parts; $i++){
      $dir .= $parts[ $i ]."/";
  }
     }


     # put the result inot the array
     $ret[++$#ret] = $dir;
 }
    }
    elsif( -d $name ){


 # this is a directory, simply check if ends with the slash
 if( not $name =~ /\/$/ ){
     $name .= "/";
 }

 $ret[++$#ret] = $name;
    }
}


# all done, print the array
foreach $name (@ret){
    print $name."\n";

}

1.2 The teen-ager code

What if I have to write a similar service today?
That is the very first code that comes into my mind:



#!env perl

use v5.20;
use File::Spec;

my @dirs;
for ( @ARGV ){
    push @dirs, $_ if ( -d $_ );
    push @dirs, ( File::Spec->splitpath( $_ ) )[ 1 ] if ( -f $_ );
}

{
    local $" = "/\n";
    say "@dirs";
}

A lot less, uh?
It could be simpler, but so far I don't know any module to return the directory part of a path when a file is provided as argument, and
this is the reason I need to distinguish between the -f and -d cases.


The adoption of the list separator $" is specific to add the trailing backslash and to place every single directory on its own line. Of course this means, as $" suggests, that the array has to be printed via doubled quoted print. Here the adoption of say
or print is totally equivalent.


Let be honest here: the adoption of local and the surrounding block could be avoided, since the script exits implicitly right after
such couple of instructions, and this means the code could even be simpler, or better, shorter, but let's keep some good habits!

Nessun commento: