When I run a simple bit of code like this:
my @arr=(1..5);
my $x;
foreach $x (@arr) {
$x+=10;
}
print "@arr";
The result is “11 12 13 14 15” because $x “becomes” each element in the @arr array in the foreach. Well enough.
But here’s my thing… not so much a problem (the solution is easy, but inelegant, and I want my perl to be as elegant as possible).
I wrote a tie module for dealing with COBOL data. It takes a copybook, parses the fields, and then attaches that to a scalar/string so that access to/from the tied hash will return/set values in the string. It works wonderfully.
my %h,$rec;
my $cb=<<END;
01 CH-RECORD.
05 JOB-NUM PIC X.
05 FILLER PIC X(76).
05 REC-TYPE PIC X(2).
END
tie %h, 'COBOLDataTie',$cb,\$rec; #tie the hash to the record via the copybook
From there, I can move a COBOL record to $rec and access the COBOL fields with the %h hash.
Again, this works perfectly. But the problem comes when I want to iterate over, say, an array of COBOL records. So if after the above code I had something akin to:
foreach $rec (@arr) {
print "Job is ",$h{'JOB-NUM'},"\n";
}
it won’t work because the foreach actually changes the location of $rec, which breaks the tie on it. I end up having to do something like this:
foreach (@arr) {
$rec=$_;
print "Job is ",$h{'JOB-NUM'},"\n";
}
Is there any way I can do the “foreach $rec (@arr)” and not break my tied hash?
(And before anyone says, yes I know this begs for a nice object-oriented solution… some day I’ll get to that; I just have to find some time first)
EPILOGUE: I revised the TieHash code to, instead of pointing to an external record, it intercepts “special” keys for the hash, among which is ‘record’. So when I assign a record string to $h{‘record’} it’s the same as loading $rec in the example above. This is a far better solution, more self-contained. It also exposes a more OOP-like interface.
It seems like the best way is to do something like:
Not exactly the elegance I was hoping for, but it seems to work.