In an ancient part of the code at work, we use
open my $output, '>-' or die $!;
Perl::Critic complains about it and wants us to replace it with a three argument variant. But, what's the 3-arg variant of >-?
I thought
open my $output, '>&', *STDOUT or die $!;
might be the same, but it isn't, cf.
open my $output, '>-' or die $!;
close *STDOUT;
print {$output} "This fails with Bad file descriptor";
versus
open my $output, '>&', *STDOUT or die $!;
close *STDOUT;
print {$output} "This prints OK\n";
Then I tried with
my $output = *STDOUT;
but it's different, too:
close STDOUT;
print {$output}
'Besides Bad file descriptor, this will also warn "print() on clos
+ed filehandle STDOUT"';
Is there a three-argument version of open that behaves the same as '>-'?
Update: Here's a SSCCE. Closing STDOUT is a global state, so call this with an argument (1, 2, 3, 4) to test a particular implementation.
#!/usr/bin/perl
use strict;
use warnings;
sub original {
open my $output, '>-' or die $!;
$output
}
sub assign {
my $output = *STDOUT;
$output
}
sub dup {
open my $output, '>&', *STDOUT or die $!;
$output
}
sub fn {
open my $output, '>>&=', *STDOUT->fileno or die $!;
$output
}
use Test::More;
sub test {
my ($open) = @_;
my @W;
local $SIG{__WARN__} = sub { push @W, @_ };
my $output = $open->();
close *STDOUT;
my $v = print {$output} "abc\n";
isnt $v, 1, 'fails';
like $!, qr/Bad file descriptor/, 'Exception';
is scalar @W, 0, 'no warnings';
chomp, diag "($_)" for @W;
done_testing();
}
my %dispatch = (1 => \&original,
2 => \&assign,
3 => \&dup,
4 => \&fn);
my $what = shift;
my $code = $dispatch{$what} or die 'Not associated';
test($code);
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.