1

How can I use a Perl function to return a boolean value and a string?

For example, I am using regular expression to find something in a string. If found, return true and assign value to $msg, otherwise return false and assign another value to $msg.

Now I want to return both $result (boolean) and $msg (String) by "return ($result, $msg); ", and it's verified working. I am wondering if it is good to do it like this or is there a better way? I don't want to make other people confused when they are looking at my code.

use constant { true => 1, false => 0 };
my $output = "hello world";
my $msg;
my $result;

sub is_string_found
{
    if ($output =~ /hello/;)
    {
        $msg = "string is found";
        $result = true;
    }
    else
    {
        $msg = "string is not found";
        $result = false;
    }

    return ($result, $msg);
}
4
  • 1
    if there's a one to one correspondence of message and result, then it might be better to only return the boolean value, and deal with the message elsewhere -- an auxiliary function, if it's used a lot. Commented May 28, 2013 at 0:00
  • 1
    that said, true and false don't really exist in perl as such. Commented May 28, 2013 at 0:00
  • I probably wouldn't have the function that finds the string be the entity that decides what is displayed if it's found or not. Usually, you'd have it just return the true/false (or 1/0 or whatever) and have the caller upstream that deals with the user decide what's displayed for a string. Commented May 28, 2013 at 0:05
  • thanks for your comments. but sometimes upstream cannot get enough info to deal with different scenarios, for example, in the code above,if "hello" is NOT found, then set $msg = "hello is not found", else if "world" is not found, then set $msg = "world is not found", and for both cases, return false. If this function only return true/false, then upstream cannot get what's the reason of true/false. Do you mean i need a getter/setter function to pass the $msg to upstream functions in this case? Commented May 28, 2013 at 0:11

2 Answers 2

3

There are a few issues with your code, aside from using constants true and false:

  • You declare $msg and $result outside of your function. It would be better to reduce the visibility of these variables just to the function. Actually, you don't even need them.

  • You pass an argument to your sub by a variable in an outer scope, and return values in the same way. Use subroutine arguments and return values instead.

  • You have an erraneous ; in your if-condition.

Your sub can be shortened to

sub is_string_found {
  my ($str) = @_;
  return 1, "string is found" if $str =~ /hello/;
  return 0, "string is not found";
}

It can then be used like

my ($ok, $message) = is_string_found("hello world");

This is the best, and most obvious solution (to a Perl programmer).


You could also use an out-argument, so that you only return the success value:

sub is_string_found ($\$) {
  my ($str, $out_ref) = @_;
  if ($str =~ /hello/) {
    $$out_ref = "string is found";
    return 1;
  } else {
    $$out_ref = "string is not found";
    return;
  }
}

return without values returns undef in scalar context, the empty list in list context. It can then be invoked like

my $ok = is_string_found "hello world", my $message;

or

my $message;
is_string_found "hello world", $message
  or log_warning $message;

Note: you have to declare the sub before you first use it, either by defining it before usage, or putting the statement sub is_string_found ($\$); near the top of the script.

You don't have to use prototypes (and can instead use the aliasing behaviour of @_), but I'm not particulary fond of that solution

Sign up to request clarification or add additional context in comments.

Comments

2

What you are doing in terms of returning a list is fine. But using a hash may arguable be better:

sub is_string_found {
    my %h; 
    if ($output =~ /hello/)
    {   
        %h = (msg=>"string is found", retval=>1);
    }
    else
    {   
        %h = (msg=>"string is not found", retval=>0);
    }
    return %h; 
}

%d = is_string_found();
print $d{msg}, "\n" if not $d{retval};

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.