Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-9348

Introduce finer control for AS keyword with maps

    XMLWordPrintableJSON

Details

    • Hide
      Given the following classes:

      class A {
          B b
          int data
          int data2
      }
      class B {
          C c
          String data
      }
      class C {
          Date data
      }

      The code works fine:

      Date now = new Date()
      def a = [ data:42, data2:84, b:[ data:'BBB', c:[ data:now ] ] ] as A
      assert a.b.c.data == now
      assert a.data == 42
      assert a.data2 == 84

      Now if I omit the data2:84, the code still works fine except for the last assert of course.

      BUT! If I "misspell" the property name like:

      def a = [ data:42, data22:84, b:[ data:'BBB', c:[ data:now ] ] ] as A

      The 1st assert fails with NPE:

          java.lang.NullPointerException: Cannot get property 'c' on null object

      and what I see is that only the A class gets instantiated with a no-arg constructor, and b and c properties are all nulls.

      To make the behaviour more persistent I can see the following options:

      * do hard-stop: throw an UnknownPropertyException in case of unknown property
      * do the best-effort cast, i.e. skip the unknown properties only, and fill-in the good ones
      * provide a control mechanism to switch between the current "silent" behaviour, maybe by introducing new keywords _asStrict_ and _asLenient_

      The case is discussed in https://stackoverflow.com/questions/59423991/groovy-as-keyword-for-map-class-binding
      Show
      Given the following classes: class A {     B b     int data     int data2 } class B {     C c     String data } class C {     Date data } The code works fine: Date now = new Date() def a = [ data:42, data2:84, b:[ data:'BBB', c:[ data:now ] ] ] as A assert a.b.c.data == now assert a.data == 42 assert a.data2 == 84 Now if I omit the data2:84, the code still works fine except for the last assert of course. BUT! If I "misspell" the property name like: def a = [ data:42, data22:84, b:[ data:'BBB', c:[ data:now ] ] ] as A The 1st assert fails with NPE:     java.lang.NullPointerException: Cannot get property 'c' on null object and what I see is that only the A class gets instantiated with a no-arg constructor, and b and c properties are all nulls. To make the behaviour more persistent I can see the following options: * do hard-stop: throw an UnknownPropertyException in case of unknown property * do the best-effort cast, i.e. skip the unknown properties only, and fill-in the good ones * provide a control mechanism to switch between the current "silent" behaviour, maybe by introducing new keywords _asStrict_ and _asLenient_ The case is discussed in https://stackoverflow.com/questions/59423991/groovy-as-keyword-for-map-class-binding

    Attachments

      1. screenshot-1.png
        22 kB
        Eric Milles

      Activity

        People

          Unassigned Unassigned
          injecteer Konstantin Smirnov
          Votes:
          0 Vote for this issue
          Watchers:
          2 Start watching this issue

          Dates

            Created:
            Updated: