AHA! I just ran into the same problem in some code I'm writing: I had assigned to the "in memory" variable after opening it. Turns out you can only concatenate to it, otherwise you have to seek to the beginning. Some examples:
# Save old STDIN and STDOUT
open my $oldin, '<&', \*STDIN or die "Can't dup STDIN:$!";
open my $oldout, '>&', \*STDOUT or die "Can't dup STDOUT:$!";
# set up new STDIN
my $invar = "foo\n";
open STDIN, '<', \$invar or die "Can't open scalar:$!";
# set up new STDOUT
open STDOUT, '>', \$outvar or die "Can't open scalar:$!";
# Try it out!
print STDERR $out; # prints "foo"
# But beware:
# $invar = "bar\n"; #BAD! try this instead:
$invar .= "bar\n";
print STDERR <>; #Would have given your manpage. Now works!
# This might work, too, but I'm not sure:
$invar = "baz\n";
seek STDIN, 0, 0;
print STDERR <>; #Not tested, should print "baz\n";
# Another caveat about STDOUT:
$outvar = ""; #This does not do what you think.
print STDERR $outvar; #prints same as "foo\nding\n"
# instead, do this:
seek STDOUT, 0, 0;
print STDERR $outvar; # this does print "dong\n" only.
# Now restore old filehandles:
open STDIN, '<&', $oldin or die "Can't redup STDIN\n";
open STDOUT, '<&', $oldout or die "Can't redup STDOUT\n";
UPDATE: the seek on STDIN works just fine. I decided to go that route because it scales better (always concatenating to my input scalar would keep increasing my memory usage.