http://qs321.pair.com?node_id=1131938

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

Is there a better way to do this? Am I using the correct idiom? Is this a bug? My Perl version is 5.18 (Mac OS Yosemite system perl)

I recently noticed that attempts to dup/restore a file handle pointing to string turns that file handle into a black hole. Writes (e.g.print) to file handle don't seem to appear in the output when the file handle is restored after dupping. New input isn't appended to the string, nor does it replace the beginning of the re-opened memory file/string.

The black hole goes away if I reopen using substr($s,length($s)) where $s is the original variable used to create the memory file handle.

Trying to reopen in append mode also results in a black hole on my macbook

Below (hidden with readmore) is a script demonstrating the problem.

use strict; use warnings; use Config; use IO::String; sub demo { my ($option) = @_; my ($s1, $s2) = ('',''); my $sFormat = "s1='%s' s2='%s'\n"; my $fh1; print STDERR "===========\n"; open($fh1, '>', \$s1) or die "Can't open fh1"; print $fh1 'Hi Thing One'; printf STDERR $sFormat, $s1, $s2; # => s1='Hi Thing One' s2='' open(my $fhSave, '>&', $fh1) or die "Can't save fh1"; close $fh1; open($fh1, '>', \$s2) or die "Can't redirect fh1"; print $fh1 'Hi Thing Two*Bye Thing Two'; printf STDERR $sFormat, $s1, $s2; # => s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two' print STDERR "Option $option"; if ($option == 1) { print STDERR " (opening in >& mode)\n"; open($fh1, '>&', $fhSave) or die "Can't restore fh1"; } elsif ($option == 2) { print STDERR " (opening on a substr)\n"; open($fh1, '>', \ substr($s1, length($s1)) ) or die "Can't restore fh1"; } elsif ($option == 3) { print STDERR " (opening in >> mode)\n"; open($fh1, '>>', $fhSave ) or die "Can't restore fh1"; } print $fh1 '*Bye Thing One'; printf STDERR $sFormat, $s1, $s2; # OUTPUT FROM OPEN OPTIONS #1# => s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two' #2# => s1='Hi Thing One*Bye Thing One' s2='Hi Thing Two*Bye Thing Tw +o' #3# => s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two' } print STDERR "\n".qq!Perl $^V on $^O arch $Config{archname}\n!; demo(1); demo(2); demo(3); print "\n"; exit(0);

The output on my macbook is

Perl v5.18.2 on darwin arch darwin-thread-multi-2level =========== s1='Hi Thing One' s2='' s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two' Option 1 (opening in >& mode) s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two' =========== s1='Hi Thing One' s2='' s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two' Option 2 (opening on a substr) s1='Hi Thing One*Bye Thing One' s2='Hi Thing Two*Bye Thing Two' =========== s1='Hi Thing One' s2='' s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two' Option 3 (opening in >> mode) s1='Hi Thing One' s2='Hi Thing Two*Bye Thing Two'

Edit1: clarified instructions for running script, more details about Perl version. Thank-you Disciplus for suggestions.

Edit 2: revised script so that it just runs without needing to uncomment anything and also prints out your perl version - once again thank-you Disciplus, this time for the idea of using config.

Edit 3: revised script to include option to reopen file in append mode - which also doesn't work on Perl 5.18 on Darwin