Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an "undefined but true" value analogous to "0 but true"?

Tags:

perl

I'm writing a search routine where undefined and zero are both valid results. I'm returning a two element array like ($result, $answer) because I don't have an "undefined but true" value. It works fine but is a bit klutzy. A class seems like overkill.

Does such a thing exist or can be faked somehow? I'm thinking of things like the 0E0 trick, etc.

More details. This is the user interface I would like. The current routine returns two values, the result (whether or not the key was found) and a value if it was.

my $result = search_struct($key, $complex_data_structure);
if ($result) {
    print "A result was found for $key!  Value is: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}
like image 764
Bill Ruppert Avatar asked Oct 08 '12 14:10

Bill Ruppert


3 Answers

You could just return a reference to the result. Return undef for no result, \( undef ) for literal undefined result, \( whatever ) for any other result. Then the caller can just use $$result (after making sure $result is defined).

like image 140
Mark Reed Avatar answered Nov 04 '22 04:11

Mark Reed


No, but there are numerous ways you can return three states.

Solution 1

  • Empty list (return;)
  • Undefined (return undef;)
  • String (return "foo";)

my $found = my ($result) = search_struct($key, $data);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

List assignment in scalar context evaluates to the number of elements returned by its right-hand side.

Solution 2

  • False (return undef;)
  • Reference to undefined (return \undef;)
  • Reference to a string (return \"foo";)

my $result = search_struct($key, $data);
if ($result) {
    print "$key: ", $$result // "Undefined!", "\n";  # Note change here!
}
else {
    print "Sorry, no result was found for $key.\n";
}

Solution 3

  • False (return 0;)
  • True, and undef (return (1, undef);)
  • True, and string (return (1, "foo");)

my ($found, $result) = search_struct($key, $data);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

Solution 4

  • False (return 0;)
  • True, undef returned as parameter ($_[2] = undef; return 1;)
  • True, string returned as parameter ($_[2] = "foo"; return 1;)

my $found = search_struct($key, $data, my $result);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

BTW, I would pass the data structure as the first parameter and the key as the second parameter. More like OO programming.

like image 29
ikegami Avatar answered Nov 04 '22 05:11

ikegami


You might return your answer in a list (not an array): empty list for no results found, and a one element list otherwise ((undef,) or ($some_answer,)).

It's still rather klunky, but:

if (my ($answer) = the_function()) { # note parentheses
  process_answer($answer);  # might be undef, false, etc.
} else {
  no_results_found();
}
like image 43
pilcrow Avatar answered Nov 04 '22 03:11

pilcrow