Reputation: 11
The next code is used to get a filepath and check if exists and can be read; otherwise the value will be switched to a custom one:
use strict;
use warnings;
[...]
sub checkFilePath{
my ($args) = @_;
my $checkingPath = $args->{path};
my $checkingCustomPath = $args->{customPath};
my $canBeRead = 1;
if ($checkingPath) {
if (!(-e "$checkingPath")) {
print "[WARN] File $checkingPath doesn't exist.\n";
$canBeRead = 0;
} elsif (!(-f "$checkingPath")) {
print "[WARN] $checkingPath is not a file.\n";
$canBeRead = 0;
} elsif (!(-r "$checkingPath")) {
print "[WARN] File $checkingPath can't be read.\n";
$canBeRead = 0;
}
}
if (!($canBeRead)) {
# Testing custom regex file path
# If doesn't exist, it will try to use custom file or the script will die
die "[ERR] Custom file $checkingCustomPath doesn't exist\n" if (!(-e $checkingCustomPath));
die "[ERR] Custom file $checkingCustomPath is not a file\n" if (!(-f $checkingCustomPath));
die "[ERR] Custom file $checkingCustomPath cannot be read\n" if (!(-r $checkingCustomPath));
return $checkingCustomPath;
}
return $checkingPath;
}
[...]
$logPath = checkFilePath({
path => $logPath,
customPath => $customLogPath
});
I was wondering if there is a way to modify this code to update $logPath
only with a subroutine call, like:
# $logPath = '/tmp/thisfiledoesntexist.txt'
checkFilePath({
path => $logPath,
customPath => $customLogPath
});
# $logPath now has a valid filepath, which is the same as $customLogPath
Upvotes: 1
Views: 207
Reputation: 118156
Thinking about this a little more, I decided to propose a different, less repetitive, and, IMO, clearer way of doing it:
use strict;
use warnings;
use autouse Carp => qw(croak);
print chooseFilePath('doesnot.exist', "$ENV{TEMP}/t.log"), "\n";
sub chooseFilePath {
my $wantedPath = shift;
my $defaultPath = shift;
if (defined(my $reason = isBadFilePath($wantedPath))) {
warn "[WARN] $reason.\n";
if (defined($reason = isBadFilePath($defaultPath))) {
die "[ERR] $reason.\n";
}
return $defaultPath;
}
return $wantedPath;
}
sub isBadFilePath {
@_ or croak 'Need a path';
my $path = shift;
-e $path or return "File '$path' doesn't exist";
-f _ or return "'$path' is not a file";
-r _ or return "File '$path' can't be read";
return;
}
Output:
C:\...\Temp> perl s.pl
[WARN] File 'doesnot.exist' doesn't exist.
[ERR] File 'C:\...\Temp/t.log' doesn't exist.
C:\...\Temp> echo x > t.log
C:\...\Temp> perl s.pl
[WARN] File 'doesnot.exist' doesn't exist.
C:\...\Temp/t.log
Upvotes: 1
Reputation: 386541
If $logPath
was passed to the subroutine as an argument (or via a reference), it would be possible to change it (by modifying the correct element of @_
(or modifying the referenced scalar)). But you copy its value into a hash and pass a reference to that hash instead. At best, you could modify $hash->{path}
instead of $logPath
.
sub fixFilePath {
our $checkingPath; local *checkingPath = \shift; # my \$checkingPath = \shift;
my %args = @_;
my $checkingCustomPath = $args{customPath};
...
return if $canBeRead;
...
$checkingPath = $checkingCustomPath;
}
fixFilePath($logPath,
customPath => $customLogPath,
);
Upvotes: 1