http://qs321.pair.com?node_id=748301

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

Hi All,
  What is this code doing?
return !!@value;


Lyle

Replies are listed 'Best First'.
Re: return !!
by zwon (Abbot) on Mar 04, 2009 at 20:06 UTC

    It returns true if array is not empty

Re: return !!
by Random_Walk (Prior) on Mar 04, 2009 at 20:07 UTC

    It is returning true if the array contains any elements, false if not.

    It take the array in scalar context (thus getting its length) and negates it, so zero length would be true, non-zero false, then negates this again.

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!
Re: return !!
by Limbic~Region (Chancellor) on Mar 04, 2009 at 20:29 UTC
    cosmicperl,
    I am suprised that no one mentioned why this convention exists. It is likely a candidate for a small "Perl Idioms Explained".

    If you are only interested in the truth of an expression, you can save some cycles by not copying the entire data. In this case, I would have preferred return scalar @array because of the way perl handles truth.

    Cheers - L~R

      you can save some cycles by not copying the entire data.

      Since the context is surely scalar, it wouldn't copy the entire data anyway.

        ikegami,
        I was speaking to the idiom not this specific example. For instance return $foo; where $foo is the contents of a large file. I also am not sure I agree that the author of the sub can be sure that the caller of the sub would be calling it in scalar context - making the explicit scalar useful.

        Cheers - L~R

Re: return !!
by webfiend (Vicar) on Mar 04, 2009 at 21:23 UTC

    It's doing a couple things, although only one of them is relevant to the execution of code:

    • As mentioned, it's returning 1 if there are any items in @value, and false otherwise.
    • It's wreaking havoc on Vim's syntax highlighting.
    • It's wreaking havoc on my own poor brain trying to parse "not not (scalar) @value".

    I'd probably use a more explicit test, as the following example shows (lexical variables added for my own peace of mind):

    use Modern::Perl; sub mean_test { my @value = @_; return !!@value; } sub nicer_test { my @values = @_; return scalar @values > 0; } say "Mean: Empty: ", mean_test(); say "Mean: One Item: ", mean_test("sweet!"); say "Mean: Two Items: ", mean_test("dude!", "sweet!"); say "Nicer: Empty: ", nicer_test(); say "Nicer: One Item: ", nicer_test("sweet!"); say "Nicer: Two Items: ", nicer_test("dude!", "sweet!");

    It evaluates the same, as far as I can tell.

    Mean: Empty:
    Mean: One Item: 1
    Mean: Two Items: 1
    Nicer: Empty:
    Nicer: One Item: 1
    Nicer: Two Items: 1
    
      The vim syntax highlighting thing can be fixed by putting a space between the bangs (! !@_).
      []s, HTH, Massa (κς,πμ,πλ)
Re: return !!
by jwkrahn (Abbot) on Mar 04, 2009 at 20:06 UTC

      Not quite.

      $ perl -wle'print 0 + sub { my @v; !!@v }->()' 0 $ perl -wle'print 0 + sub { my @v; @v ? 1 : "" }->()' Argument "" isn't numeric in addition (+) at -e line 1. 0

      And it doesn't return zero for false either.

      $ perl -wle'print "" . sub { my @v; !!@v }->()' $ perl -wle'print "" . sub { my @v; @v ? 1 : 0 }->()' 0

      False is actually dualvar(0, '')

Re: return !!
by Lawliet (Curate) on Mar 04, 2009 at 20:24 UTC

    It's an idiom to return the correct boolean for an expression.

    And you didn't even know bears could type.

Re: return !!
by zentara (Archbishop) on Mar 04, 2009 at 20:08 UTC