example: optional attribute with a default value
authorJean Privat <jean@pryen.org>
Wed, 5 Aug 2015 18:47:32 +0000 (14:47 -0400)
committerJean Privat <jean@pryen.org>
Wed, 5 Aug 2015 22:34:44 +0000 (18:34 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

tests/sav/test_autoinit_optional.res [new file with mode: 0644]
tests/test_autoinit_optional.nit [new file with mode: 0644]

diff --git a/tests/sav/test_autoinit_optional.res b/tests/sav/test_autoinit_optional.res
new file mode 100644 (file)
index 0000000..4e88d43
--- /dev/null
@@ -0,0 +1,26 @@
+Mine
+Default
+Other
+Default
+
+Mine
+Default
+Other
+Default
+Yet Another
+
+Mine
+Default
+Other
+Default
+
+Mine
+Default
+Other
+Default
+
+Mine
+Default
+Other
+Other
+Yet Another
diff --git a/tests/test_autoinit_optional.nit b/tests/test_autoinit_optional.nit
new file mode 100644 (file)
index 0000000..9be0277
--- /dev/null
@@ -0,0 +1,126 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This test provides variations on having an attribute with a default value but optionally settable with the constructor
+# The main points of variation here is what are the basic exposed services and behavior
+
+# The attribute is stored as not nullable but manual setter with a nullable signature is exposed
+# Setting with `null` invoke the real setter with the default value.
+# The manual setter is used as an initializer thus collected in the autoinit.
+#
+# Best option if one wants to allow the user to reset the default (with null) once the object is created
+class A
+       var s: String is noautoinit, private writable(real_s=)
+       fun s=(v: nullable String) is autoinit do self.real_s = v or else "Default"
+end
+
+# The attribute is stored as not nullable with standard automatic getter/setter
+# The initializer is a manual method that accepts the nullable value and assigns the default value if null is given.
+#
+# Best option if the default can only be set a construction time
+class B
+       var s: String is noautoinit
+       protected fun s_opt=(v: nullable String) is autoinit do self.s = v or else "Default"
+end
+
+# The attribute is stored as nullable.
+# A manual getter is used to return a default value if the attribute is null.
+#
+# Shortest solution without annotation.
+# Con: the default is determined by the getter and never stored (this could be an issue if the default is complex)
+class C
+       protected var s_opt: nullable String
+       fun s: String do return s_opt or else "Default"
+end
+
+# The attribute is stored as nullable.
+# A manual getter is used to return a default value if the attribute is null.
+#
+# Longer solution without annotation but the getter lazily computes and stores the default once
+class D
+       protected var s_opt: nullable String
+       fun s: String do
+               var res = s_opt
+               if res != null then return res
+               res = "Default"
+               s_opt = res
+               return res
+       end
+end
+
+# The attribute is stored as not nullable with standard automatic getter/setter
+# The initializer is manual method that accepts the nullable value and does nothing if null is given.
+#
+# This one has a tricky behavior if one accesses to `s` before `s_opt=` is executed
+class E
+       var s = "Default" is lazy
+       protected fun s_opt=(v: nullable String) is autoinit do if v != null then s = v
+end
+
+var a2 = new A("Mine")
+print a2.s
+var a1 = new A
+print a1.s
+a1.s = "Other"
+print a1.s
+a1.s = null
+print a1.s
+
+print ""
+
+var b2 = new B("Mine")
+print b2.s
+var b1 = new B
+print b1.s
+b1.s = "Other"
+print b1.s
+b1.s_opt = null
+print b1.s
+b1.s_opt = "Yet Another"
+print b1.s
+
+print ""
+
+var c2 = new C("Mine")
+print c2.s
+var c1 = new C
+print c1.s
+c1.s_opt = "Other"
+print c1.s
+c1.s_opt = null
+print c1.s
+
+print ""
+
+var d2 = new D("Mine")
+print d2.s
+var d1 = new D
+print d1.s
+d1.s_opt = "Other"
+print d1.s
+d1.s_opt = null
+print d1.s
+
+print ""
+
+var e2 = new E("Mine")
+print e2.s
+var e1 = new E
+print e1.s
+e1.s = "Other"
+print e1.s
+e1.s_opt = null
+print e1.s
+e1.s_opt = "Yet Another"
+print e1.s