jawright has asked for the wisdom of the Perl Monks concerning the following question:

wise and venerable monks... I'm runnning perl 5.8.1 on OS X, 10.3.4. my code:
#!/usr/bin/perl -p use strict; use Net::FTP; use POSIX qw(strftime); my $filedir='./'; my $localfile='index.html'; my $bkup='index.html.tmp'; my $ftpserver='127.0.0.1'; my $ftpdir=""; my $user='scott'; my $password='tiger'; my $insertpoint='<!--insert here-->'; my $dateformat="%A, %d %B %Y, %H:%M:%S"; my $datestring=strftime($dateformat,localtime); my $headline=''; my $post=''; my $ftpfl=0; chdir($filedir) or die "can't chdir:$!\n"; my $old_fh=select(STDOUT); $| = 1; select($old_fh); print "\nheadline:\n"; do{ if ($headline eq ''){ $headline=$_; print "post:\n"; }else{ $post.=$_; } }while(<STDIN>); print "headline: $headline\npost: $post\n"; open(ORIG,"< $localfile") or die "can't open $localfile:$!"; open(BKUP,"> $bkup") or die "can't open $bkup:$!"; select(BKUP); while(<ORIG>){ print BKUP $_ or die "can't write $bkup:$!"; if ($_ =~ m/$insertpoint/ && $post =~ /^[A-Za-z]+$/){ print BKUP "<div class=box><strong>$datestring $headline</stro +ng>\n"; print BKUP "<p class=post> $post</p></div>\n" or die "can't wr +ite to $bkup:$!"; $ftpfl=1; } } close(ORIG) or die "can't close $localfile:$!"; close(BKUP) or die "can't close $bkup:$!"; if ($ftpfl){ print "renaming...\n"; rename($localfile, "$localfile.orig") or die "can't rename $localf +ile to $localfile.orig:$!"; rename($bkup,$localfile) or die "can't rename $bkup to $localfile: +$!"; print "transferring...\n"; my $ftp=Net::FTP->new($ftpserver) or die "Can't connect:$@\n"; $ftp->login($user, $password) or die "can't login\n"; $ftp->cwd($ftpdir) or die "can't cwd to $ftpdir\n"; $ftp->put($localfile) or die "can't put $localfile\n"; }
i'm sure there's more than a few glaring errors, as it's been some time since i tried my hand at perl..but, the biggest problem so far is that STDOUT isn't acting as if it is flushed. when i run this, i see nothing until i start to enter data. once i hit the first carriage return, i see both prompts. I type the rest of the data, hit ^D, and see no other output...even though the files get updated. I know it's a newbie question, and I've R'd the FM, but i still don't see it.

Replies are listed 'Best First'.
Re: can not flush stdout
by derby (Abbot) on Jul 10, 2004 at 10:45 UTC
    First problem is the first line:
    #!/usr/bin/perl -p
    You really don't want the -p option here ... from perlrun:
    -p causes Perl to assume the following loop around your program, which makes it iterate over filename arguments somewhat like sed: LINE: while (<>) { ... # your program goes here } continue { print or die "-p destination: $!\n"; }
    that's why you need to enter a carriage return. If there are no arguments, the while(<>) idiom will open and read STDIN.

    -derby
Re: can not flush stdout
by muba (Priest) on Jul 10, 2004 at 21:24 UTC
    First, you should have a look at the first reply on your node. I think there's some valuable information in there.

    Second, I'm glad you at least put <CODE> tags around your code but a little more layout won't hurt. For example: just use white lines to separate the parts of code (variable initialisation and different parts of the real code) :) This is not meant to assault you in any way, it's just offered as an advice.

    Thirth thing, think about what you're actually trying to achieve. For example:
    my $old_fh=select(STDOUT); $| = 1; select($old_fh);
    default, STDOUT is selected. So, $old_fh refers to STDOUT now. Then you select STDOUT and make it to flush automatically. Then, you select $old_fh which refers to STDOUT. I really had a hard time while trying to understand what you was actually trying to do here.
    Again, not trying to assault you, but what you're doing here is just: $| = 1 in three lines, where the other two lines only are like "Hey MUBA, what is your nick name?".




    "2b"||!"2b";$$_="the question"
      Thanks for all the advice. I've always appreciated how constructive the criticism is here...i in no way took that as an assault. That bit of code to which you referred kept being repreated in every article I found on unbuffering output. It was usually written for file handles other than STDOUT, but since nothing else i'd tried had worked (thanks to '-p') I tried it. It did look odd to me, but "all the articles were doing it". Now, that I've taken out the -p, I'll rip out the superfluous lines as well.