Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.0.5
-
None
Description
Given this class:
@Grab( 'org.clojure:clojure:1.4.0' ) import clojure.lang.PersistentList import clojure.lang.PersistentVector //@groovy.transform.Immutable(knownImmutableClasses=[List]) class Broken { List list Broken( List list ) { this.list = list } Broken cons( Object v ) { new Broken( list.cons( v ) ) } String toString() { "$list" } } def a = new Broken( PersistentList.EMPTY.cons( 'tim' ) ) println a.cons( 'yates' ) def b = new Broken( PersistentVector.EMPTY.cons( 'tim' ) ) println b.cons( 'yates' )
We get the output:
[yates, tim] [tim, yates]
However, if we annotate the class as Immutable (and get rid of the constructor and the toString as would be required)
@Grab( 'org.clojure:clojure:1.4.0' ) import clojure.lang.PersistentList import clojure.lang.PersistentVector @groovy.transform.Immutable class Broken { List list Broken cons( Object v ) { new Broken( list.cons( v ) ) } } def a = new Broken( PersistentList.EMPTY.cons( 'tim' ) ) println a.cons( 'yates' ) def b = new Broken( PersistentVector.EMPTY.cons( 'tim' ) ) println b.cons( 'yates' )
We now get the output:
Caught: groovy.lang.MissingMethodException: No signature of method: java.util.Collections$UnmodifiableList.cons() is applicable for argument types: (java.lang.String) values: [yates] Possible solutions: join(java.lang.String), count(groovy.lang.Closure), count(java.lang.Object), sort(), find(), any() groovy.lang.MissingMethodException: No signature of method: java.util.Collections$UnmodifiableList.cons() is applicable for argument types: (java.lang.String) values: [yates] Possible solutions: join(java.lang.String), count(groovy.lang.Closure), count(java.lang.Object), sort(), find(), any() at Broken.cons(PList3.groovy:10) at Broken$cons.call(Unknown Source) at PList3.run(PList3.groovy:15)
So the transformation has changed our List field into a UnmodifiableList, and I can no longer call the PersistentVector or PersistentList methods on it.
Changing the transformation to:
@groovy.transform.Immutable(knownImmutableClasses=[List])
Makes no change
Is there (or could there be added) a way of saying that you know that a given field is an Immutable type?
Cheers,
Tim