: Hi folks! Perl newbie in need of assistance

. I've got array
: @dir_list, with bunch of entries like "/home/something/else" and I
: want to extract the last part, that is "else".
:
: I did it like this:
:
: for($i = 0 ; $i <= $#dir_list ; $i++) {
This loops through all elements of the array @dir_list
: @tmp_fields = split /\//, "$dir_list[$i]";
and performs an operation on them, the results being assigned to a temp
array
: $dirnames[$i] = $tmp_fields[$#tmp_fields];
from which we build a third array consisting of the last element of the temp
array
: }
:
: Since I'm an extreme Perl newbie (started learning it this afternoon
::>), I'm just wondering is there a better, or more standard way of
: doing stuff like this?
The File::Basename module provides some functions for handling file paths,
but is also trivial to deal with in a regex. A single regex is not portable
(between win32, unix, mac etc) but for most small script purposes this is
not important. It should be borne in mind however.
Several ways to deal with this come to mind...
for (@dir_list){ # loop through array
if (m/.*\/(.*)/){ # capture part after last /
push @dirnames, $1: # push into array
}
}
This can be written as:
for (@dir_list){ # loop construct
push @dirnnames, $1 if m|.*/(.*)|; # test and assign
}
We test if the regex match succeeded before assigning the capture ($1)
because if not we might assign something we don't want.
The two regexes above, whilst the look different are actually the same. The
second one uses different delimiters for the match operator in order to
avoid backwacking the slash which can lead to 'leaning toothpick syndrome'
wherein it becomes hard to read what is part of the regex and what is an
escape. The regex works because it is greedy. The first .* grabs
everything, and then the regex backtracks until the / can match with the .*
following matching everything else. The parens capture everything after the
matched / into the first default variable $1.
Here is one using map:
@dirnames = map {m{.*/(.*)}} @dir_list;
Note the different delimiters for the match operator, this time m{} instead
of m|| or m//. The outer braces form the BLOCK for the map function. BTW,
using // is the only time you can drop the m// and write it like
/.*\/(.*)/;
instead of
m/.*\/(.*)/;
HTH