in reply to One liner: split fixed-width field into equal length chunks...

Whenever you find yourself numbering individual variables instead of giving them names, you should recognise that what you ought to be using is an array.

It does away with the need for eval and it is automatically extensible.

A second thing I notice in your code is that your use of substr is wrong. The 3rd parameter to substr is the number of bytes, not the end position of the substring. As you have shown it, your variables will get larger and larger in length:

$d1 = substr($field, 0, 2); # 2 bytes $d2 = substr($field, 2, 2+2); # 4 bytes $d3 = substr($field, 4, 4+6); # 6 bytes etc.

You also show $i+=$n in the loop increment, $i-1/$n to generate your varnames, but a fixed value of 2 in the substr?

There are several ways to do what you want without using eval or symbolic refs.

my @d; for my $i (0 .. $length-$n) { $d[$i] = substr($field, $i*$n, $n) }

Or

my @d = map{ substr $field, $_*n, $n } 0 .. ($length)/$n;

Or

my @d = unpack("A$n " x $length/$n, $field);

Or probably the simplest

my @d = $field =~ m[.{1,$n}]g;

Examine what is said, not who speaks.
1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
3) Any sufficiently advanced technology is indistinguishable from magic.
Arthur C. Clarke.

Replies are listed 'Best First'.
Re^2: One liner: split fixed-width field into equal length chunks...
by Aristotle (Chancellor) on Mar 21, 2003 at 23:58 UTC
    Whenever you find yourself numbering individual variables instead of giving them names, you should recognise that what you ought to be using is an array.
    Obligatory reading for more of such fundamental advice: Mark-Jason Dominus' excellent Program Repair Shop and Red Flags article series on Perl.com.

    Makeshifts last the longest.

      Yes, I realize this. I guess I've been programming in languages where dynamic arraying is impractical for so long that I forget that perl has such flexibility.

      I didn't want to declare an array of a fixed size... and if I did, I didn't want to use an explicit for-loop (not sure why not, but the little voice in the back of my head said "hey, this is perl... you probably don't need a for loop to do that... it can probably happen in one line... it's probably a really short line, you idiot!")

      Thanks for the resources, I'll read up on them! (couldn't wait, read the first... wow... so many of my programs to unbreak)
Any sufficiently advanced technology is indistinguishable...
by mr. jaggers (Sexton) on Mar 25, 2003 at 04:56 UTC
    Or probably the simplest

    my @d = $field =~ m[.{1,$n}]g;

    OH... it is beautiful! I just plugged it into "filename -> hash" function to convert filenames such as "access_log.03020700.gz" into hashes that are something like:
    { type => "access_log", year => "03", month => "02", day => "07", hour => "00" compressed => "1" }
    ... needless to say, logfile munging of usage statistics is going splendidly now!

    I feel like I've graduated from 1st grade of perl primary school... I'm actually Extracting Practical Reports from data!