1

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
0

2 Answers 2

1

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,
);
Sign up to request clarification or add additional context in comments.

6 Comments

I don't understand why this answer was downvoted, so, +1 from me.
I've tried to modify $hash->{path} at the end of the subroutine but when it ends customLogPath hasn't changed. The line I coded is {args->{customPath} = 'Testing';. Doing a print inside and outside of the sub I get different values
Re "I've tried to modify $hash->{path} at the end of the subroutine", Always use use strict;!!! $hash doesn't exist.
Re "The line I coded is {args->{customPath} = 'Testing';", (I'm assuming you meant $args->{customPath} = 'Testing';.) Always use use strict;!!! $args doesn't exist.
Yes, I always use strict; on my script. And {args was a typo. I was talking about $args, which exists in my original subroutine (my ($args) = @_;). So that's why I'm getting different values, and I don't understand why
|
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.