my %handler = ( HEADER => sub { ... }, TITLE => sub { ... }, COMPND => sub { ... }, ); my ($tag, $text) = ("")x2; while(<>) { chomp; my ($curr_tag, $curr_text) = split /\s+/, $_, 2; if($curr_tag ne $prev_tag) { $handler{$tag}->($tag, $text) if exists $handler{$tag}; # complain_about_unknown() if not exists $handler{$tag}; ? ($tag, $text) = ($curr_tag, ""); } else { my $curr_linenr; ($curr_linenr, $curr_text) = split /\s+/, $curr_text, 2; # perform validation on line nr here? } $text .= " " . $curr_text; } #### my %record; my %handler = ( # ... TITLE => sub { $record{TITLE} = $_[1] unless exists $record{TITLE} }, # ... ); #### my $curr_rec = 0; my @record; my %handler = ( # ... HEADER => sub { ++$curr_rec }, TITLE => sub { $record[$curr_rec]->{TITLE} = $_[1] unless exists $record[$curr_rec]->{TITLE} }, # ... );