Re:Perl: When DWIM Doesn't
by douglashunter on Tuesday January 31, 2012 @12:04PM
(#3534094)
> Both above spot the undef gotcha.
The builtin open() even tries to spot when it's not intentional. The documentation puts "undef" in quotations in the section where it introduces the feature (suggesting it has to be the literal), and the implementation goes to some effort to agree with it. For example, the following code dies:
my $config = { file_paht => "/opt/config" };
my $path = $config->{file_path};
open (my $fh, "<", $path)
or die "can't open $path: $!";
In the case in the article it's a bug in the implementation, combined with a typo, which introduces the little known feature.Using Path::Class obfuscates the open, to my eyes. Using IO::File is a nice suggestion. Your lock_keys suggestion below will probably be our update to the code for future protection, though.
re: Path::Class - Each to their own :)
However you can take your original full example of this:
open (my $fh, "<", $config->{file_path})
or die "can't open $config->{file_path}: $!";
my $data;
{
local $/ = undef;
$data = <$fh>;
}
And turn it into just this with Path::Class use Path::Class 'file';
my $data = file( $config->{file_path} )->slurp
When dealing with lots of files/directories especially across different platforms I find Path::Class a god send.NB. One good habit I currently do have is using Path::Class more ubiquitously :)
!!! Supplementary for future readers of this comment thread !!!
The pragma autodie also spots this problem!
So....
use strict;
use warnings;
use autodie;
our $config;
$config->{file_paht} = "somefile";
open my $fh, '<', $config->{file_path};
Will throw an exception at open(). NB. Bizarrely the error is Use of uninitialized value $file in sprintf... but hey the problem is still caught :)
Fortunately both IO::File (core module) & Path::Class don't do this:
Both above spot the undef gotcha. NB. And ->openr() throws an exception.ref: https://metacpan.org/module/IO::File | https://metacpan.org/module/Path::Class