in reply to printing and logging to a file

You can use btrott's Filter::Handle. (Untested code ahead.)
use Filter::Handle; my $logfile = "program.log"; open(LOG, ">", $logfile) or die "Cannot write to '$logfile': $!"; Filter( \*STDOUT, sub { print LOG @_; return @_; } );
Note the gotchas documented in the module involving system calls, xsubs, etc due to how tie works in Perl. Another solution is to pipe your output to a program that does your log and STDOUT. On Unix the "tee" program would usually be chosen for this. Solutions involving passing data to an external program do not suffer from the limitations above.

UPDATE
To answer the second question, I suggest reading Suffering from Buffering by Dominus.