学习高阶Perl:迭代器问题

前端之家收集整理的这篇文章主要介绍了学习高阶Perl:迭代器问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我研究了高阶Perl书,并在第4.3.4章中讨论了迭代器问题.

代码

main_script.pl

  1. #!/perl
  2. use strict;
  3. use warnings;
  4.  
  5. use FindBin qw($Bin);
  6. use lib $Bin;
  7. use Iterator_Utils qw(:all);
  8. use FlatDB;
  9.  
  10. my $db = FlatDB->new("$Bin/db.csv") or die "$!";
  11. my $q = $db->query('STATE','NY');
  12. while (my $rec = NEXTVAL($q) )
  13. {
  14. print $rec;
  15. }

Iterator_Utils.pm

  1. #!/perl
  2. use strict;
  3. use warnings;
  4. package Iterator_Utils;
  5. use Exporter 'import';;
  6. our @EXPORT_OK = qw(NEXTVAL Iterator
  7. append imap igrep
  8. iterate_function filehandle_iterator list_iterator);
  9. our %EXPORT_TAGS = ('all' => \@EXPORT_OK);
  10. sub NEXTVAL { $_[0]->() }
  11. sub Iterator (&) { return $_[0] }

FlatDB.pm

  1. #!/perl
  2. use strict;
  3. use warnings;
  4.  
  5. package FlatDB;
  6.  
  7. my $FIELDSEP = qr/:/;
  8.  
  9. sub new
  10. {
  11. my $class = shift;
  12. my $file = shift;
  13.  
  14. open my $fh,"<",$file or return;
  15. chomp(my $schema = <$fh>);
  16.  
  17. my @field = split $FIELDSEP,$schema;
  18. my %fieldnum = map { uc $field[$_] => $_ } (0..$#field);
  19. bless
  20. {
  21. FH => $fh,FIELDS => \@field,FIELDNUM => \%fieldnum,FIELDSEP => $FIELDSEP
  22. } => $class;
  23. }
  24.  
  25. use Fcntl ':seek';
  26. sub query
  27. {
  28. my $self = shift;
  29. my ($field,$value) = @_;
  30. my $fieldnum = $self->{FIELDNUM}{uc $field};
  31. return unless defined $fieldnum;
  32. my $fh = $self->{FH};
  33. seek $fh,SEEK_SET;
  34. <$fh>; # discard schema line
  35. return Iterator
  36. {
  37. local $_;
  38. while (<$fh>)
  39. {
  40. chomp;
  41. my @fields = split $self->{FIELDSEP},$_,-1;
  42. my $fieldval = $fields[$fieldnum];
  43. return $_ if $fieldval eq $value;
  44. }
  45. return;
  46. };
  47. }

db.csv

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

就像到目前为止的书一样,对吗?但是我没有得到输出(应该出现Adler和Schwern的字符串).错误消息是:

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

我究竟做错了什么?

提前致谢!

解决方法

FlatDB调用Iterator,它在Iterator_Utils中定义,因此它需要从Iterator_Utils导入该函数.如果你添加
  1. use Iterator_Utils qw(Iterator);

在包FlatDB之后,该程序将起作用.

非常感谢您发现此错误.我将此添加the errata on the web site.如果您希望通过名称记入帐户,请将您的姓名发送给我.

猜你在找的Perl相关文章