我研究了高阶Perl书,并在第4.3.4章中讨论了迭代器问题.
代码:
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,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
就像到目前为止的书一样,对吗?但是我没有得到输出(应该出现Adler和Schwern的字符串).错误消息是:
- 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.
我究竟做错了什么?
提前致谢!