2
1
0

I see inconsistent use of the "?" character. In some examples it is present, but in other examples is it not.


Outgoing rule:
replica.customFields."Custom field name" = issue.customFields."Local custom field name"


Incoming rule:
issue.customFields."Local custom field name".value = replica.customFields."Custom field name".value


vs


issue.customFields​."Labels".value + = replica.customFields."label - cust1"?.value



In the first set of rules, there is no "?" anywhere, but in the second on there is a single "?" in the replica, yet no matching "?" in the issue side. In other examples I have seen it on both ends of the equation, but others, apparently identical in construction, do not have it at all. I have no idea what it actually does or why I should use/not use it.


When should I use the "?" or not? Is there a scripting syntax guide that explains this somewhere? I have looked for one but not found it yet.

    CommentAdd your comment...

    2 answers

    1.  
      2
      1
      0

      Francis has provided all the details you need.


      But to answer your question to the point, I'd like to leave some of my understanding here:


      ?  used before a dot (.) operator to make it a "safer dot" operator.


      Because if the object before the dot is Null, then an expression like this: 

      object.name  will throw exception NullPointerException

      while 

      object?.name will just return Null, without throwing exception, hence safer for the case you want to say: If object is NOT null, then return its name, else return null


      You would NOT want use this operator on the left side of an assignment of course, because if it is, there will be case where the left side become Null and you will assign something to a null space. 


      Hope this clarifies your questions. 




        CommentAdd your comment...
      1.  
        1
        0
        -1

        The '?' operator is called the 'Save Navigation' operator - a groovy construct allowing to avoid nullpointer exceptions


        for instance 


        // generates a NullPointerException
        def foo = null
        shouldFail(NullPointerException) {
            def bar = foo.value
        }
        
        



        while

        // avoid the null pointer exception
        def foo = null
        assert(foo?.value, null)



        More information on this can be found here



        Also interesting is the Elvis Operator ?:

        It allows to construct items like



        // typeName becomes Task if replica.typeName == null
        issue.typeName = replica.typeName ?: "Task"


        PS.  The snippets on the documentation site are snippets. Due are indeed due for a review.

          CommentAdd your comment...