Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Corrupt Data?

by ikegami (Patriarch)
on Jul 14, 2008 at 20:36 UTC ( [id://697565]=note: print w/replies, xml ) Need Help??


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)

Replies are listed 'Best First'.
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
      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?
      []s, HTH, Massa

      The first argument of map is code executed for every other argument of map.

      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).

        I would have used "W" instead of "A"

        The reason I used "A" is because it works in older Perls, too, like 5.8.8.  "W" is available in 5.10 only.

      "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

      Unless I state otherwise, all my code runs with strict and warnings

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://697565]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (1)
As of 2024-04-25 02:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found