nando has asked for the wisdom of the Perl Monks concerning the following question:

UPDATED

I'm trying to do with "map" what does this code using a loop

#!/usr/local/bin perl5.14.2 + use warnings; use strict; use File::Basename; my @extens = qw(.zip .dmg .tar.gz .pl .pl~ .cgi .mp3 .txt); my @ppal; my $i = 0; foreach my $arch (@ARGV ){ my ($name,$path,$suffix) = fileparse($arch,@extens); $ppal[$i] = []; push @{$ppal[$i]},($path,$name,$suffix); $i++; } foreach my $elem (@ppal){ print "Path:\t@{$elem}[0]\tArchivo:\t@{$elem}[1]\tExtens:\t@{$elem +}[2]\n"; }

Although as I say below, it is a simple exercise. I do not know whether it makes sense to map this

As I said in previous comments, I am learning to use map, (which means that, right now, I use it even, probably, in those circumstances should not be used). I'm following the book "Intermediate Perl", which in its second chapter discusses the module "File:: basename".Great!, (I said to myself), I will map it.

The most obvious solution for me is to use a loop "foreach" but never have consented that the evidence is to be preferred to my whims.

This code works correctly (although with some problems with file names that contain a "space". Later I'll look how that settle it the module):

#!/usr/local/bin perl5.14.2 + use File::Basename; my @sufijos = qw(.dmg .tar.gz .rar .zip); foreach $arch (@ARGV) { + $name = basename( $arch, @sufijos); print "Nombre: $name\n"; }

I have begun to try something like this:

#!/usr/local/bin perl5.14.2 + use File::Basename; my @sufijos = qw(.dmg .tar.gz .rar .zip); sub parsear { my $input = shift; $name = basename ( $input, @sufijos ); } print map &parsear($_)."\n" , @ARGV;

In "@ ​​ARGV" stores the output of a command 'ls'

This works as expected ... But ... What if I want to parse a full path by using the "fileparse" that will output an array? I guess the solution is the use of references. You would want to explain how to do ... Not so much the solution as a little explanation to understand the "hows" and "whys".

Do not think I'm obsessed with the "map" is just to learn.

PS: I leave you, it seems that my implementation of map for the microwave is giving problems. XD

Replies are listed 'Best First'.
Re: Complex structures and function "map"
by ikegami (Patriarch) on Oct 21, 2011 at 18:24 UTC

    I don't see how your problem has anything to do with map. It appears that you don't know how to return values from a sub.

    sub parsear { my $input = shift; $name = basename ( $input, @sufijos ); }
    is basically the same as
    sub parsear { my $input = shift; return $name = basename ( $input, @sufijos ); }

    If you want to return one of elements of the arraylist returned by fileparse, you have a few alternatives.

    Temporary storage:

    sub parsear { my $input = shift; my ($name, $path, $suffix) = fileparse( ... ); return $name; }

    List slice:

    sub parsear { my $input = shift; return ( fileparse( ... ) )[0]; }

    Relying on the fact that fileparse returns the right value in scalar context:

    sub parsear { my $input = shift; return scalar( fileparse( ... ) ); }

    PS — Use use strict; use warnings;! Also, I wouldn't use "&" in front of sub calls. This has an effect (ignoring the prototype) you should only use when needed.

      Thank you

      But what I want is to store the three variables, not one of them. An array of arrays formed by the list that generates the "fileparse"

      ;)
        map doesn't store anything, it returns a list. What list do you want it to return, a list of references to arrays?
        sub func { ... return \@a; } map { func(...) } ...
        sub func { ... return [ ... ]; } map { func(...) } ...
        sub func { ... return ...; } map { [ func(...) ] } ...
Re: Complex structures and function "map"
by ikegami (Patriarch) on Oct 23, 2011 at 11:05 UTC

    You posted this code:

    use warnings; use strict; use File::Basename; my @extens = qw(.zip .dmg .tar.gz .pl .pl~ .cgi .mp3 .txt); my @ppal; my $i = 0; foreach my $arch (@ARGV ){ my ($name,$path,$suffix) = fileparse($arch,@extens); $ppal[$i] = []; push @{$ppal[$i]},($path,$name,$suffix); $i++; } foreach my $elem (@ppal){ print "Path:\t@{$elem}[0]\tArchivo:\t@{$elem}[1]\tExtens:\t@{$elem +}[2]\n"; }

    It could use some cleanup:

    use warnings; use strict; use File::Basename; my @extens = qw(.zip .dmg .tar.gz .pl .pl~ .cgi .mp3 .txt); my @ppal; foreach my $arch (@ARGV) { push @ppal, [ fileparse($arch, @extens) ]; } foreach my $elem (@ppal) { print "Path:\t${$elem}[0]\tArchivo:\t${$elem}[1]\tExtens:\t${$elem +}[2]\n"; #or: print "Path:\t$elem->[0]\tArchivo:\t$elem->[1]\tExtens:\t$ele +m->[2]\n"; #or: printf "Path:\t%s\tArchivo:\t%s\tExtens:\t%s\n", @$elem; }

    To introduce map, change

    my @ppal; foreach my $arch (@ARGV) { push @ppal, [ fileparse($arch, @extens) ]; }
    to
    my @ppal = map { [ fileparse($_, @extens) ] } @ARGV;
Re: Complex structures and function "map"
by nando (Acolyte) on Oct 23, 2011 at 15:42 UTC

    Thank you. I think I'm understanding.