fix #15, default toString for a class
+default comparison for a class !give up struct in favor of class (simpler)
This commit is contained in:
parent
2a93e6f7da
commit
652e1d3af4
17
docs/OOP.md
17
docs/OOP.md
@ -141,7 +141,24 @@ set at construction but not available outside the class:
|
||||
void
|
||||
>>> void
|
||||
|
||||
## Default class methods
|
||||
|
||||
In many cases it is necessary to implement custom comparison and `toString`, still
|
||||
each class is provided with default implementations:
|
||||
|
||||
- default toString outputs class name and its _public_ fields.
|
||||
- default comparison compares compares all public fields in order of appearance.
|
||||
|
||||
For example, for our class Point:
|
||||
|
||||
class Point(x,y)
|
||||
assert( Point(1,2) == Point(1,2) )
|
||||
assert( Point(1,2) !== Point(1,2) )
|
||||
assert( Point(1,2) != Point(1,3) )
|
||||
assert( Point(1,2) < Point(2,2) )
|
||||
assert( Point(1,2) < Point(1,3) )
|
||||
Point(1,1+1)
|
||||
>>> Point(1, 2)
|
||||
|
||||
# Theory
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Declaring arguments in Lyng
|
||||
|
||||
It is a common thing that occurs in many places in Lyng, function declarations,
|
||||
lambdas, struct and class declarations.
|
||||
lambdas and class declarations.
|
||||
|
||||
## Regular
|
||||
|
||||
|
@ -26,4 +26,23 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
||||
if( name in publicFields ) return instanceContext[name]!!.value.invoke(context, this, args)
|
||||
return super.invokeInstanceMethod(context, name, args)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val fields = publicFields.map {
|
||||
instanceContext[it]?.value?.toString() ?: "??"
|
||||
}.joinToString(", ")
|
||||
return "${objClass.className}($fields)"
|
||||
}
|
||||
|
||||
override suspend fun compareTo(context: Context, other: Obj): Int {
|
||||
if( other !is ObjInstance ) return -1
|
||||
if( other.objClass != objClass ) return -1
|
||||
for( f in publicFields ) {
|
||||
val a = instanceContext[f]!!.value
|
||||
val b = other.instanceContext[f]!!.value
|
||||
val d = a.compareTo(context, b)
|
||||
if (d != 0) return d
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
@ -1386,7 +1386,7 @@ class ScriptTest {
|
||||
fun testSimpleStruct() = runTest {
|
||||
val c = Context()
|
||||
c.eval("""
|
||||
struct Point(x,y)
|
||||
class Point(x,y)
|
||||
assert( Point::class is Class )
|
||||
val p = Point(2,3)
|
||||
assert(p is Point)
|
||||
@ -1405,7 +1405,7 @@ class ScriptTest {
|
||||
fun testNonAssignalbeFieldInStruct() = runTest {
|
||||
val c = Context()
|
||||
c.eval("""
|
||||
struct Point(x,y)
|
||||
class Point(x,y)
|
||||
val p = Point("2",3)
|
||||
assert(p is Point)
|
||||
assert( p.x == "2" )
|
||||
@ -1420,7 +1420,7 @@ class ScriptTest {
|
||||
fun testStructBodyVal() = runTest {
|
||||
val c = Context()
|
||||
c.eval("""
|
||||
struct Point(x,y) {
|
||||
class Point(x,y) {
|
||||
val length = sqrt(x*x+y*y)
|
||||
var foo = "zero"
|
||||
}
|
||||
@ -1440,7 +1440,7 @@ class ScriptTest {
|
||||
fun testStructBodyFun() = runTest {
|
||||
val c = Context()
|
||||
c.eval("""
|
||||
struct Point(x,y) {
|
||||
class Point(x,y) {
|
||||
fun length() {
|
||||
sqrt(x*x+y*y)
|
||||
}
|
||||
@ -1487,4 +1487,30 @@ class ScriptTest {
|
||||
assertEquals( 1, cond { 1 } )
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testClasstoString() = runTest {
|
||||
eval("""
|
||||
class Point {
|
||||
var x
|
||||
var y
|
||||
}
|
||||
val p = Point()
|
||||
p.x = 1
|
||||
p.y = 2
|
||||
println(p)
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testClassDefaultCompare() = runTest {
|
||||
eval("""
|
||||
class Point(x,y)
|
||||
assert( Point(1,2) == Point(1,2) )
|
||||
assert( Point(1,2) !== Point(1,2) )
|
||||
assert( Point(1,2) != Point(1,3) )
|
||||
assert( Point(1,2) < Point(2,2) )
|
||||
assert( Point(1,2) < Point(1,3) )
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user