The following example shows how I/O can be simply redirected:
open(F, '>/tmp/x') || die;
*STDOUT = *F;
print "hello world\n";
The print function thinks it is sending the output to STDOUT but ends up sending it to the open file instead, because the typeglob associated with STDOUT has been aliased to F. If you want this redirection to be temporary, you can localize *STDOUT.