Learning High-Order Perl: An Iterator Problem

I am studying a high-order Perl book and have a problem with iterators in chapter 4.3.4.

Code:

main_script.pl

#!/perl use strict; use warnings; use FindBin qw($Bin); use lib $Bin; use Iterator_Utils qw(:all); use FlatDB; my $db = FlatDB->new("$Bin/db.csv") or die "$!"; my $q = $db->query('STATE', 'NY'); while (my $rec = NEXTVAL($q) ) { print $rec; } 

Iterator_Utils.pm

 #!/perl use strict; use warnings; package Iterator_Utils; use Exporter 'import';; our @EXPORT_OK = qw(NEXTVAL Iterator append imap igrep iterate_function filehandle_iterator list_iterator); our %EXPORT_TAGS = ('all' => \@EXPORT_OK); sub NEXTVAL { $_[0]->() } sub Iterator (&) { return $_[0] } 

FlatDB.pm

 #!/perl use strict; use warnings; package FlatDB; my $FIELDSEP = qr/:/; sub new { my $class = shift; my $file = shift; open my $fh, "<", $file or return; chomp(my $schema = <$fh>); my @field = split $FIELDSEP, $schema; my %fieldnum = map { uc $field[$_] => $_ } (0..$#field); bless { FH => $fh, FIELDS => \@field, FIELDNUM => \%fieldnum, FIELDSEP => $FIELDSEP } => $class; } use Fcntl ':seek'; sub query { my $self = shift; my ($field, $value) = @_; my $fieldnum = $self->{FIELDNUM}{uc $field}; return unless defined $fieldnum; my $fh = $self->{FH}; seek $fh, 0, SEEK_SET; <$fh>; # discard schema line return Iterator { local $_; while (<$fh>) { chomp; my @fields = split $self->{FIELDSEP}, $_, -1; my $fieldval = $fields[$fieldnum]; return $_ if $fieldval eq $value; } return; }; } 

db.csv

 LASTNAME:FIRSTNAME:CITY:STATE:OWES Adler:David:New York:NY:157.00 Ashton:Elaine:Boston:MA:0.00 Dominus:Mark:Philadelphia:PA:0.00 Orwant:Jon:Cambridge:MA:26.30 Schwern:Michael:New York:NY:149658.23 Wall:Larry:Mountain View:CA:-372.14 

Like the book, huh? However, I do not get the result (lines with Adler and Fill should happen). Error message:

  Can't use string ("Adler:David:New York:NY:157.00") as a subroutine ref while "strict refs" in use at N:/Perle/Learn/Iterators/Iterator_Utils.pm line 12, <$fh> line 3. 

What am I doing wrong?

Thanks in advance!

+6
source share
1 answer

FlatDB calls Iterator , which is defined in Iterator_Utils , so it needs to import this function from Iterator_Utils . If you add

 use Iterator_Utils qw(Iterator); 

after package FlatDB , the program will work.

Thanks so much for discovering this error. I will add this to the errors on the website . If you want to be credited by name, write me your name.

+8
source

All Articles