http://qs321.pair.com?node_id=1212579

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

Hi Monks.

I'm currently improving my Perl by practising Perl idioms and trying to write more 'Perlish' code. I'm currently practising by parsing a binary blob with unpack.

My input is a scalar, and my desired output is an array of arrays.

As I'm from a C background my initial approach is to use the C-like for loop and I end up with code like the following:

#!/usr/bin/env perl use strict; use warnings; use 5.016; use Data::Dumper; my $data = "1ABCD2EFGH3IJKL4MNOP5QRST6UVWX"; my $entry_size = 5; my @out; for (my $off = 0; $off < length $data; $off += $entry_size) { my $item = substr ($data, $off, $entry_size); push @out, [unpack "CA*", $item]; }; print Dumper \@out;

While it works, it seems unnecessarily verbose for Perl and I'm aware I'm trying to write C in Perl.

Therefore, I've been attempting to rewrite the code in a more Perlish manner. I've ended up with the following:

#!/usr/bin/env perl use strict; use warnings; use 5.016; use Data::Dumper; my $data = "1ABCD2EFGH3IJKL4MNOP5QRST6UVWX"; my $entry_size = 5; my @items = unpack "(a$entry_size)*", $data; my @out = map { [unpack "CA*"] } @items; print Dumper \@out;

I'm happy with the map { unpack ... } ... construct as this is clear and concise, but I'm a little less sure about the first unpack to split the $data scalar into the list of items.

Therefore I'm deferring to the wisdom of the Monks, is there a better way to achieve what I am doing? Maybe the approach should be a single unpack "(CA4)*", $data and then rebuilding the child lists?