in reply to Corrupt Data?
Aside from what's already been said,
my $j = 0; for ($j; $j<$length; $j++)
could be better written as
for (my $j = 0; $j<$length; $j++)
and even better as
for my $j (0..$#array)
Re^2: Corrupt Data?
by spickles (Scribe) on Jul 14, 2008 at 21:28 UTC
|
Thanks for the discussion everyone...I always do my homework first, but the web has just as many bad examples and poorly written documentation as it does good ones. In any case, the goal here is for all of us, particularly myself, to become better programmers. To that end, since I didn't find any examples as unique as Almut's use of the unpack function, do I understand its use thusly:
return - we want to return a value
map - we're going to use the map function to evaluate each array node
"AP" . join "." - I understand what this is doing, but I don't understand from any documentation what the first argument to map is, generally speaking (everything before the first comma)
unpack - I see from documentation that the capital 'A' for unpack refers to any ASCII character with its whitespace, but again I don't understand from documentation that you can add the ordinal and/or * along with it, and how that modifies the query
lc $_ - perform the lowercase operation on the current scalar/node of the array
@_ - Store the results to the unnamed array @_
If anyone has any additional comments and/or suggestions regarding my understanding, please feel free. In addition, any suggestions for comprehensive documentation is appreciated. I currently use search engines to find as many examples of a particular piece of code until it clicks with me and I understand it.
Regards,
Scott
| [reply] |
|
I will (too) try to explain and detail almut's answer:
my @mac_addrs = ("0015FAA3F03A", "0015FAA3F03B", "0015FAA3F03C");
sub convert {
return map { "AP" . join ".", unpack "(A4)*", lc $_ } @_;
}
print "$_\n" for convert(@mac_addrs);
Well:
- @answer = map { do_something_with("$_") } @array transforms one @array into another array @answer where each element of @answer is the result of the transform do_something_with(). Try this:
$ perl -le '@a = (2, 3, 4, 5); @b = map { 2 * $_ } @a; print for @b'
4
6
8
10
Notice that @b has each of the elements of @a, doubled. The result of the block given to map can be an array, too, so:
$ perl -le '@a = (2, 3, 4, 5); @b = map { $_ % 2 ? () : ($_, $_ / 2) }
+ @a; print for @b'
2
1
4
2
Notice that it printed the number and its half -- for the even numbers in @a.
- So, let's try the knowledge of map:
$ perl -le '@mac_addrs = ("0015FAA3F03A", "0015FAA3F03B", "0015FAA3F03
+C"); @a = map { lc $_ } @mac_addrs; print for @a'
0015faa3f03a
0015faa3f03b
0015faa3f03c
- Now, let's add unpack"(A4)*" to the equation (unpack any number of groups of four alphanumeric chars):
$ perl -le '@mac_addrs = ("0015FAA3F03A", "0015FAA3F03B", "0015FAA3F03
+C"); @a = map { unpack "(A4)*", lc $_ } @mac_addrs; print for @a'
0015
faa3
f03a
0015
faa3
f03b
0015
faa3
f03c
- Now, let's join the parts with ".":
$ perl -le '@mac_addrs = ("0015FAA3F03A", "0015FAA3F03B", "0015FAA3F03
+C"); @a = map { join ".", unpack "(A4)*", lc $_ } @mac_addrs; print f
+or @a'
0015.faa3.f03a
0015.faa3.f03b
0015.faa3.f03c
- And then, add the "AP" in the beginning:
@mac_addrs = ("0015FAA3F03A", "0015FAA3F03B", "0015FAA3F03C"); @a = ma
+p { "AP" . join ".", unpack "(A4)*", lc $_ } @mac_addrs; print for @a
+'
AP0015.faa3.f03a
AP0015.faa3.f03b
AP0015.faa3.f03c
- voilą!! you already have your answer. Now, package everything in a neat subroutine:
$ perl -le '
> use strict;
> my @mac_addrs = ("0015FAA3F03A", "0015FAA3F03B", "0015FAA3F03C");
> sub convert {
> map { "AP" . join ".", unpack "(A4)*", lc $_ } @_
> }
> print for convert @mac_addrs
> '
AP0015.faa3.f03a
AP0015.faa3.f03b
AP0015.faa3.f03c
Got it?
| [reply] [d/l] [select] |
|
print map uc($_), qw( a b c d ); # Prints ABCD
print map { uc($_) } qw( a b c d ); # Same thing
unpack '(A4)*', $val splits the value into as many 4 byte blocks as possible. I would have used "W" instead of "A", though. unpack '(W4)*', $val splits the value into as many 4 character blocks as possible.
@_ is not unamed —its name is @_— and nothing is being stored in it —its contents are being passed to map.
@_ holds the arguments of the current function (convert).
| [reply] [d/l] [select] |
|
| [reply] |
|
|
|
| [reply] |
|
|
|
"AP" . join "." - I understand what this is doing, but I don't understand from any documentation what the first argument to map is, generally speaking (everything before the first comma)
map this, that will do this to each element of that, with $_ being aliased to each of the elements
For example
my @in = 1 .. 5;
my @out = map $_ * 2, @in; # doubles each element of @in
@out = map $_ * 2, 1 .. 5; # same thing - any list will do
| [reply] [d/l] |
|
|