morgon has asked for the wisdom of the Perl Monks concerning the following question:

Hi

my new toy is urxvt which is a terminal emulator that can be extended with (yay) perl.

Skimming throught the documentation on how to write extensions I came across this piece of advice:

All of these hooks must return a boolean value.
...
When in doubt, return a false value (preferably "()").

I am a bit baffled as to why "()" should make a better false value as say "undef" but I am sure there is a reason for this.

Anyone with an idea?

Many thanks!

  • Comment on What could make "()" a good value for boolean false?

Replies are listed 'Best First'.
Re: What could make "()" a good value for boolean false?
by Anonymous Monk on Mar 27, 2016 at 20:59 UTC
    return (); is the same as return;, which returns an empty list when the sub is called in list context and a false value when the sub is called in scalar context. On the other hand, return undef; always returns one value from the sub: undef. When that sub is called in list context, it returns a list consisting of one element (undef). Because that list has one element, when you evaluate it in boolean context, it's true! See also Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef.
      That makes sense - thanks.

      So is return (); as opposed to simply return; (the two behave the same) a widely accepted convention or just a matter of personal taste?

        So is return (); as opposed to simply return; (the two behave the same) a widely accepted convention or just a matter of personal taste?

        its not a convention, there are no conventions ... its extra typed chars that serve no purpose , don't see why anyone would adopt that as a style or a convention ...

        > (the two behave the same)

        no, they do the same!

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

        I hope not, because I'm opposed to it. Sub that are expected to return a scalar shouldn't suddenly return nothing. It causes subtle problems that aren't caught by the compiler.

        Consider what happens if type suddenly returned nothing instead of `undef`:

        my $h = { type => type(), name => name(), };

        return (); should be used for subs that are expected to return a list.

        return undef; should be used for subs that are expected to return a scalar. There are exceptions, of course.

Re: What could make "()" a good value for boolean false? (updated)
by LanX (Saint) on Mar 27, 2016 at 21:07 UTC
    > I am a bit baffled as to why "()" should make a better false value as say "undef"

    sub tst { return undef } means returning a one element list in list context.

    so @a = tst() is true in if(@a) {..} (length is one)

    FWIW for me a blank return; is best for false. (i.e. returning an empty list implicitely )

    And the empty list evaluates to undef again in scalar context.

    update

    I've been a bit sloppy in my wording, Perl doesn't return a list!

    The return statement is evaluated in the call context (one of the weirdnesses which were adressed in Perl6).

    But this is not relevant when retuning just one undef.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

Re: What could make "()" a good value for boolean false?
by Marshall (Canon) on Mar 29, 2016 at 00:44 UTC
    If the objective of the hook is to return a Boolean, return 1; or return 0;. I find the idea of sometimes returning 1 and in the case of "false" returning nothing a bad idea.

    Yes, a "bare return" return;, will return "nothing" which can be interpreted as "undef" in the caller's code.

    "return 0;" is crystal clear. I am returning a false value and I expect you as the caller to check this value. A simple "return;" is also used in the context where there is NO return value and I do not expect the caller to check it. I argue to make the code crystal clear. Geez if this code returns a Boolean, then there must some code somewhere like "return 1;", mirror that for the false value with "return 0;".

      return 0 is not false in list context! It suffers from the same problem as return undef described elsewhere in this thread. And ...==0 is not how you check for falsehood in Perl! If you really, really wanted to explicitly return a false value that is not undef and avoid the above problem, you'd have to write "return wantarray?():!1". But since you're writing a function that is evaluated in boolean context, that's unnecessary, since undef is just as false. So I suggest that if you don't like the looks of "return;", write "return; # return false" instead.

        A list with one element is true

        Nope. It's impossible to evaluate whether it's true or false.

        return 0 is not false in list context!

        It's not true either. The concept of truth of something in list context makes no sense.

        This list context idea doesn't appear to have anything to do with the requirements for a "hook" for this terminal emulator. The hook returns something that is evaluated in a scalar context. When the hook fails, it should: return 1;. The suggestion for when the hook succeeds is to end the sub with simply (), instead of even a return! Ok, if that is what you want to do, then I would agree that "return;" is better than a simple "()". Perl will return the value of the last statement in a sub if there is no explicit return. I argue that return (0); is better than a simple () or bare "return;" when the objective is to return a simple scalar true/false.

        One of the pages that talks about this: Hooks. You can see some examples of code at Example Hook Code. It is clear to me that the intent is a simple true/false that will be evaluated in a scalar, not list context.