When my sub needs to pass back some output thru one of the parameters (return value is already used to pass back another output), a run-time error occurs when that parameter holds a constant from the caller. Example:
# Increases the input by 1 and reports if the new value is bigger than 10.
sub IncreaseByOne {
$_[0] ++;
return ($_[0] > 10 ? 1 : 0);
}
my $x = 1;
IncreaseByOne($x); # This is OK.
IncreaseByOne(1); # This is not OK.
My question: Is there a way within the sub to tell if $_[0] is read only? (I understand that many would say it is not a good practice to return information thru one of parameters. But I really need to in my situation.)
If the sub is supposed to increment the value, then it should fail if that's not possible: don't surprise users by silently ignoring a problem. That error is a good thing!
But if really necessary, you can test whether the scalar is readonly:
use Scalar::Util 'readonly';
sub IncreaseByOne {
readonly($_[0]) or $_[0]++;
...
}
Note that instead of using out-parameters (which leads to unexpected problems like you experienced), it is often better to return a list of multiple values:
sub IncreaseByOne {
my ($x) = @_;
$x++;
my $more_than_ten = ($x > 10);
return $x, $more_than_ten;
}