package MyDataParser; # parses a file or handle of MyData use Moose; use Moose::Util::TypeConstraints; use IO::File; subtype 'MyFile' => as class_type('IO::File'); coerce 'MyFile' => from 'Str' => via { IO::File->new($_) }; has file => ( isa => 'MyFile', is => 'rw', coerce => 1 ); sub parse { my $self = shift; my $file = $self->file; my $re_tag = qr/ ^ \{ ([A-Z]+) \} $ /x; my @records = (); my %record; my $tag; # iterate the file while ( <$file> ) { # We found a tag if ( /$re_tag/ ) { # save the new tag name because we use the value often my $ntag = lc $1; unless ( keys %record ) { # create the first record (only happens on the first line) %record = ( $ntag => '' ); } else { # otherwise cut off the last newline of input chomp $record{$tag} if $tag; # initialize an empty value for the tag $record{$ntag} = ''; # we found a new record if ( $ntag eq 'it' ) { # save the data as a record object push @records, MyDataRecord->new(%record); } } # remember current tag for the next iterations $tag = $ntag; next; } # not a tag, so add the data to the current tags value $record{$tag} .= $_; } # save the last record, since there is no final {IT} push @records, MyDataRecord->new(%record); return \@records; }