| | 645 | == I/O バッファ == |
| | 646 | sys* な I/O 操作関数の間違った使い方をすると酷い目に遭うというお話 |
| | 647 | |
| | 648 | * iotest.pl |
| | 649 | {{{ |
| | 650 | #!perl |
| | 651 | use strict; |
| | 652 | use warnings; |
| | 653 | use IO::File; |
| | 654 | use Fcntl qw(:seek); |
| | 655 | |
| | 656 | my $io = IO::File->new($0); |
| | 657 | |
| | 658 | $io->sysseek( 0, SEEK_END ); |
| | 659 | printf "%s\n", defined( $io->getline() ) ? "defined" : "undef"; |
| | 660 | |
| | 661 | while (1) { |
| | 662 | if ( defined( my $line = $io->getline() ) ) { |
| | 663 | my $h = `hostname`; |
| | 664 | print $line; |
| | 665 | next; |
| | 666 | } |
| | 667 | sleep(1); |
| | 668 | } |
| | 669 | |
| | 670 | __END__ |
| | 671 | }}} |
| | 672 | * 実行 |
| | 673 | {{{ |
| | 674 | $ perl iotest.pl |
| | 675 | undef |
| | 676 | }}} |
| | 677 | * 実行中に別端末から追記 |
| | 678 | {{{ |
| | 679 | $ echo -en "hogehoge\nfoofoo\n" >> iotest.pl |
| | 680 | }}} |
| | 681 | |
| | 682 | 最大 1 秒後に追記された行が表示されるかと思いきや,そうはならない (少なくとも 5.8.8 では). |
| | 683 | |
| | 684 | ポインタがファイル先頭から 9 バイト ("hogehoge\n") 目に移動し, |
| | 685 | そこからファイル内容が全て読み出される. |
| | 686 | |
| | 687 | 8 行目の sysseek を seek に変更すれば解決する. |
| | 688 | |