Sure, it makes sense. I guess my confusion originated in other uses with Strings. Like this:

foo = 'hello'
foo = foo ?: 'goodbye' // foo == 'hello'

where foo ends up being set to 'hello'. I guess a String as the left hand side expression of the Elvis operator evaluates to itself instead of boolean true. While it seems to be true that if it's null, it's the same as false? Like this:

foo = null
foo = foo ?: 'goodbye'  // foo == 'goodbye'

So a null reference is equivalent to boolean false. I guess that makes sense. The cases that surprise me the most are these:

foo = '' // empty string
foo = foo ?: 'goodbye' // foo == 'goodbye'

and

foo = ' ' // single space
foo = foo ?: 'goodbye' // foo = ' '

I guess I should RTFM a little more thoroughly :-)

-H

On 4/12/16 12:54 AM, Tankerbay wrote:
Well, you seem to know what's happening.
sleepFor = sleepFor > 0 ?: 10
is equivalent to:
sleepFor = (sleepFor > 0 ) ?: 10

So the entire expression (sleepFor > 0) is evaluated and, if found to be true, returned as the result of the elvis expression.

Elvis operator like this:
Z = X ?: Default
is equivalent to:
Z = X ? X : Default
not
Z = X ? (some part of X) : Default


On Mon, Apr 11, 2016 at 3:43 PM, Henrik Martin <hen...@netgate.net <mailto:hen...@netgate.net>> wrote:

    And of course I meant to say "... and my println statement prints
    10", not 910. :-)

    -H


    On 4/12/16 12:41 AM, Henrik Martin wrote:

        Greetings. I ran into this little surprise with the Elvis
        operator today. I guess it must boil down to my
        misunderstanding of how the operator work. I have a method
        that tries to calculate a value based on an input. If the
        input value is set to -1, I'd like to change it to a positive
        value (which is calculated, but in the test I just hard coded
        it to 10). In the process of doing so, I ran into a surprise.
        Here's a Spock test case that illustrates it:

        import spock.lang.Specification

        class ElvisTest extends Specification {
          def "test"() {
            setup:
            def sleepFor = -1
            sleepFor = sleepFor > 0 ?: 10
            println sleepFor
            sleepFor = 972
            sleepFor = sleepFor > 0 ?: 10
            println sleepFor
          }
        }
        When sleepFor is initialized to -1, the operator works as I
        expected it and my println statement prints 910. If I
        initialize sleepFor to some other value like the one in the
        test, all of a sudden the result of the Elvis operator is true
        instead of an integer. I naïvely thought that ?: would yield
        the numeric value of the sleepFor variable in the left hand
        expression instead of the boolean result of it (as in sleepFor
        > 0). What am I missing? In this case, I could always use the
        Java style of:

        sleepFor = sleepFor > 0 ? sleepFor : 10

        but the whole point of the Elvis operator is brevity, and this
        behavior was a small surprise to me. Thanks,

        -H




Reply via email to