You guys sure write weird
open calls. I keep thinking you’re making an easy thing hard.
Here are some examples of mine from recent programs. Those without error checking are operating under the use autodie pragma.
rename: unless (open(TTYIN, "</dev/tty") && open(TTYOUT,">/dev/tty
+")) { ... }
tcgrep: no strict "refs";
tcgrep: # use same handlename as filehandle for better warn/die me
+ssages
tcgrep: unless (open($file, $file)) { ... }
unichars: open(STDOUT, "|- :utf8", $his_pager, @pager_args);
unilook: # can't do this many arguments in old perls
unilook: if ($] >= 5.013_000) {
unilook: open($look_fh, "-| :utf8", $lookpath, $look_word, $DB
+_Name, );
unilook: } else {
unilook: open($look_fh, "$lookpath '$look_word' '$DB
+_Name' |");
unilook: binmode($look_fh, ":utf8");
unilook: }
unilook: open(my $raw_db, "< :utf8", $DB_Name);
unilook: open($agrep_fh, $arg_string);
unilook: open(STDOUT, "|- :utf8", $his_pager);
uninames~: my $unistd = "$Config{privlib}/unicore/NamesList.tx
+t";
uninames~: my $mode_in = "< :encoding(Latin-1)",
uninames~: my $mode_out = ":utf8";
uninames~: open(my $fh, $mode_in, $unistd)
uninames~: || die "can't open $mode_in '$unistd': $!";
uninames: open(STDOUT, "| $pager")
uninames: || die "can't open STDOUT to $pager pipe: $!";
uniprops: open(my $pod_fh, "< $unipod")
uniprops: || die "can't open $unipod: $!";
uniprops: open(STDOUT, "| $pager")
uniprops: || die "can't open pipe to $pager: $!";
Although my favorite has to be this from uniquote:
unshift(@ARGV, "-") if @ARGV == 0;
FILE:
for my $quasi_filename (@ARGV) {
# don't let magic open make an output handle
my $file = $quasi_filename;
$file = "standard input" if $file eq q(-);
debug("opening $file");
$quasi_filename =~ s/^(?=[\h\v]*[>|])/< /;
# Down the rabbit hole: I'm using filehandle names that match
# the handles themselves to aid in debugging message. Silly
# perl thinks this is somehow symbolic dereferencing.
no strict "refs";
my $fh = $file; # is *so* a lexical filehandle!!!
unless (open($fh, $quasi_filename)) {
yuck("couldn't open $quasi_filename: $!");
next FILE;
}
set_encoding($fh, $file) || next FILE;
LINE: for(;;) {
my $line = eval {
use warnings "FATAL" => "all";
scalar <$fh>;
};
if ($@) {
$@ =~ s/ at \K.*? line \d+.*/$file line $./;
yuck("read failure: $@");
if ($. == 0) { last LINE }
else { next LINE }
}
last LINE unless defined $line;
last LINE unless length $line;
...
See how easy that is? Why make things so hard on yourselves? Always use parens on you function calls, and you will never go astray. So simple it’s impossible to forget. And no more precedence problems.
--tom