Process files in a directory and upload them to URL I have some code that I wrote for a personal project which takes, as arguments, a directory and a URL. It then processes the files in the named directory, archives them, and uploads the archive to the specified URL.

I have heard that there are many ways to do this(TIMTOWTDI), particularly, with globs. I am hesitant to change working code, but I am interested in possible optimizations that may be possible with "globbing".

What can I do to make my code more idiomatic?

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper qw(Dumper);
use File::Spec qw(catfile rel2abs);
use Digest::SHA qw(sha256_hex);
use Archive::Tar;
use JSON;
use HTTP::Request::Common;
use LWP::UserAgent;

my $dir = $ARGV[0];
my $url = $ARGV[1];
my $fullpath;
my $fullsize;
my $fullid;
my @AoH;
my @checksumfiles;
my $archive = "archive.tar.gz";

opendir DIR, $dir or die "cannot open dir $dir: $!\n";
chdir $dir or die "cannot navigate to dir $dir: $!\n";

while(my $file = readdir DIR) {
    next unless(-f File::Spec-&gt;catfile($dir, $file));
    next if($file =~ m/^\./);

    $fullpath = File::Spec-&gt;rel2abs($file);
    $fullsize = -s File::Spec-&gt;catfile($dir, $file);
    $fullid   = sha256_hex($fullpath);

    my %hash = (
        path    =&gt;  $fullpath,
        size    =&gt;  $fullsize,
        id      =&gt;  $fullid,
    );

    push(@AoH, \%hash);
}
my @array;
for my $i(0..$#AoH) {
    no warnings 'uninitialized';
    my ($ext) = $AoH[$i]{path} =~ (/(\.[^.]+)$/);
    my $idext = $AoH[$i]{id} . $ext;
    push(@checksumfiles, $idext);
    push(@array, $AoH[$i]{path});
}

my $manifest = JSON-&gt;new-&gt;pretty-&gt;encode(\@AoH);

my $filename = "manifest.json";
open my $fh, '&gt;', $filename or die "could not open file $filename: $!\n";
print $fh $manifest;
close $fh;

my $tar = Archive::Tar-&gt;new;
$tar-&gt;add_files(@array);
$tar-&gt;write($archive);
my @file_objs = $tar-&gt;read($archive);

for my $i(0..$#file_objs) {
    $file_objs[$i]-&gt;rename($checksumfiles[$i]);
}

$tar-&gt;add_files($manifest);
$tar-&gt;write($archive, COMPRESS_GZIP);

my $browser = LWP::UserAgent-&gt;new;
my $useragent = LWP::UserAgent-&gt;new(
    env_proxy   =&gt; 1,
    keep_alive  =&gt; 1,
    timeout     =&gt; 120,
    agent       =&gt; 'Mozilla/5.0',
);

my $req = POST $url,
    Content_Type    =&gt; 'form-data',
    Content         =&gt; [ pageAction =&gt; 'upload', file =&gt; [$archive] ];

$useragent-&gt;request($req);

#print Dumper sort \@array;
#print Dumper sort \@checksumfiles;
#print Dumper sort \@AoH;
Your code is already pretty good, you have to tighten a scope of lexical (my) variables. Also as non-perl related, always get rid of unnecessary loops.

use strict;
use warnings;
use Data::Dumper qw(Dumper);
use File::Spec qw(catfile rel2abs);
use Digest::SHA qw(sha256_hex);
use Archive::Tar;
use JSON;
use HTTP::Request::Common;
use LWP::UserAgent;

my ($dir, $url) = @ARGV;
my $archive = "archive.tar.gz";

my @AoH;
my @checksumfiles;
my @array;
# same as glob("$dir/*")
while (my $file = &lt;$dir/*&gt;) {
    -f $file or next;

    my $fullpath = File::Spec-&gt;rel2abs($file);
    my %h = (
        path    =&gt;  $fullpath,
        size    =&gt;  -s $file,
        id      =&gt;  sha256_hex($fullpath),
    );
    push @AoH, \%h;

    my ($ext) = $h{path} =~ /(\.[^.]+)$/;
    # defined or
    my $idext = $h{id} . $ext // ''; # fix codereview coloring */
    push @checksumfiles, $idext;
    push @array, $h{path};
}

# my @array;
# for my $i (0..$#AoH) {
    # no warnings 'uninitialized';
    # my ($ext) = $AoH[$i]{path} =~ (/(\.[^.]+)$/);
    # my $idext = $AoH[$i]{id} . $ext;
    # push(@checksumfiles, $idext);
    # push(@array, $AoH[$i]{path});
# }