Reputation: 49
Is it possible in Perl to use a function's return value as the expression in an "if" statement? For example; in C I can write
if (!myFunction()){
printf("myFunction returned false.\n");
} else {
printf("myFunction returned true\n");
}
But in perl I find I must go through the pain of ..
$ret = myFunction();
if (!$ret){
print "myFunction returned false.\n";
}
I know as soon as I post this someone will redirect me to several other posts of this question. But, obviously, I could not find what I'm looking for or I would not write this! So spare me the "have you tried searching for ...." messages!
Here is what myFunction() looks like.
sub myFunction
{
my ($run, $runTime) = @_;
my ($code);
eval {
$SIG{ALRM} = sub {die "Operation Timed Out";};
alarm($run_time);
$EXIT_STR = `$run`; # Execute $run and save output in EXIT_STR
$code = $?; # Save cmd exit code.
$EXIT_CODE = $code; # Set a global value (EXIT_CODE)
alarm(0);
return($code);
};
if ($@) {
if ($@ =~ /Operation Timed Out/) {
print "Time out\n";
return(10);
}
}
}
After everyone's feedback I went back to the books to learn more about eval. After a bit of reading it was clearer that "eval" "returned" a value to the function it was part of. It was then up to me to decide what to do with the eval results. With that in mind I made some changes and the function works as I had hoped. Thanks to all!
Upvotes: 2
Views: 10630
Reputation: 35208
You're attempting to call return
for your subroutine from inside an eval
. This will not perform as you expect as explained in the docs for return
:
The bug you're facing can be demonstrated in the following example:
sub myFunction {
eval {
return "inside eval";
};
return "outside eval";
}
print myFunction();
Outputs:
outside eval
To fix your subroutine, assign your return value inside the eval, but actually return it from outside. Also, be sure to localize your alarm signal handler.
sub myFunction {
my ($run, $runTime) = @_;
my $code;
eval {
local $SIG{ALRM} = sub {die "Operation Timed Out";};
alarm($run_time);
$EXIT_STR = `$run`; # Execute $run and save output in EXIT_STR
alarm(0);
$code = $?; # Save cmd exit code.
};
if ($@) {
if ($@ =~ /Operation Timed Out/) {
print "Time out\n";
$code = 10;
}
}
return $code;
}
Upvotes: 0
Reputation: 733
You may need to explicitly return a false value in cases where you don't want the function to return True. Remember that perl functions will return the last evaluated statement in the absence of a real return value. So, take this example:
#!/usr/bin/perl
use warnings;
use strict;
my $x = 4;
my $y = 1;
if ( ! myFunction($x,$y) ) {
print "myFunction returned false\n";
} else {
print "myFunction returned true\n";
}
sub myFunction {
my ($x,$y) = @_;
my $response;
if ( $x + $y == 2 ) {
$response = "fun";
} else {
$response = "no fun";
}
}
This will always print 'myFunction returned true' since either branch of the conditional is technically a true response. However, if you add a return value to the negative branch of the conditional, it will now work:
#!/usr/bin/perl
use warnings;
use strict;
my $x = 4;
my $y = 1;
if ( ! myFunction($x,$y) ) {
print "myFunction returned false\n";
} else {
print "myFunction returned true\n";
}
sub myFunction {
my ($x,$y) = @_;
my $response;
if ( $x + $y == 2 ) {
$response = "fun";
return 1; # technically not really needed
} else {
$response = "no fun";
return 0;
}
}
$ perl test_funct.pl
myFunction returned false
Upvotes: 0
Reputation: 107060
Yup.
Wait. I can't give such a short answer...
Yes. If a function is inside an if statement, Perl will take the return value of the function as a boolean value. If the return value is zero, a blank string, a null value, a null string, or an undef, the if
statement will be considered false. Otherwise, the if
statement will be considered true.
Here's an easy to understand example:
if ( not is_odd( $number ) ) {
print "$number is divisible by two\n";
}
sub is_odd {
my $number = shift;
return $number % 2; # Modulo arithmetic
}
In the above $number % 2
will return zero on even numbers and one on odd numbers.
It's a good question. The best thing to do is to write a small script to try it out. Play around with it a bit:
For example. Let's add a second function we can use:
sub is_even {
my $number = shift;
return not is_odd( $number );
}
What does this return? How does this work in an if statement?
Upvotes: 1
Reputation: 86774
This will work fine.
The only caveat is that using it in an if-statement will provide scalar context to the return value so if something non-scalar is returned, it will get scalarized before the if condition is evaluated.
Upvotes: 0