Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: How to get contents from an array inside a hash

by GrandFather (Saint)
on Dec 05, 2014 at 23:37 UTC ( [id://1109394]=note: print w/replies, xml ) Need Help??


in reply to How to get contents from an array inside a hash

There are quite a few bugs happily tucked away in that code. A few coding techniques will help find many of them:

  1. Remove cruft. If you don't use the contents of a variable remove it ($cnt_all_fields etc.). That doesn't fix bugs, but it gives them fewer places to hide.
  2. Declare variables in the smallest scope you can. Don't use globals if you can possibly avoid them. @chars is an interesting case in point and probably relates to a bug.
  3. Use named variables rather than arrays. That doesn't fix bugs either, but makes code intent more obvious. @fields is the first example - use my ($key, $pos, $len, $use) = split ',', $line; instead.
  4. Don't invent your own variant of undef. Perl already has its own version and can help spot bugs for you if you use it with warnings on. Variables are undef by default and arrays and hashes are empty by default so you don't need to set them to that state. See the various layout variables for example.
  5. Don't reuse variable names for different variable types - that way madness lies. Example: @layout_value and $layout_value. Perl helps catch more bugs if you avoid overloaded names and the code is easier to understand.
  6. Perl is a real wizz at string handling. You should almost never need to loop over a string and pull characters out one by one! It's slow and harder than it needs to be to understand.

Ok, that's enough to be going on with. Here's a somewhat "cleaned up" version of your code. It probably still doesn't work as you want, but at least a few gremlins have been shaken loose:

use strict; use warnings; use List::MoreUtils qw{ any }; my $cnt_records_read = 0; my $layout = <<'LAY'; StudentLastName,180,30,Y,,Y StudentFirstName,210,30,N,,Y StudentMiddleName,240,30,N,, DateOfBirth,270,8,Y,,Y Gender,278,2,Y,,Y Grade,280,3,Y,, LAY my %layout; my @params = qw(Name Position Length); open my $layoutFile, '<', \$layout; while (defined (my $line = <$layoutFile>)) { chomp $line; my ($name, $pos, $len, $use) = split ",", $line; next if $use ne "Y"; @{$layout{$name}}{@params} = ($name, $pos - 1, $len); } close $layoutFile; my @records; my @fieldNames = sort keys %layout; while (my $line = <DATA>) { push @records, {}; for my $param (@fieldNames) { my $field = $layout{$param}; my $data = substr $line, $field->{Position}, $field->{Length}; $records[-1]{$param} = $data; } } for my $record (@records) { for my $name (@fieldNames) { printf "%-30s %8s %6s %s\n", @{$layout{$name}}{@params}, $record->{$name}; } } __DATA__ 111E2000 + 111E2000 + 201457660112567001 EP015F + SSHS 12232006 +01120 00 0 000 0 111 0 0 + sumsoc12S EPEN SS HS + NNNNNNNNNN 0000091323 + Y 111E2000 + 111E2000 + 201457660212567002 EP025F + SSHS 12232006 +01120 00 0 000 0 111 0 0 + sumsoc12S EPEN SS HS + NNNNNNNNNN 0000091324 + Y 111E2000 + 111E2000 + 201457660312567003 EP035F + SSHS 12232006 +01120 00 0 000 0 111 0 0 + sumsoc12S EPEN SS HS + NNNNNNNNNN 0000091325 + Y

which prints:

DateOfBirth 269 8 12232006 Gender 277 2 01 Grade 279 3 120 StudentLastName 179 30 EP015F + DateOfBirth 269 8 12232006 Gender 277 2 01 Grade 279 3 120 StudentLastName 179 30 EP025F + DateOfBirth 269 8 12232006 Gender 277 2 01 Grade 279 3 120 StudentLastName 179 30 EP035F
Perl is the programming world's equivalent of English

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1109394]
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: (5)
As of 2024-04-16 17:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found