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
|
||||||
>>> 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
|
# Theory
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Declaring arguments in Lyng
|
# Declaring arguments in Lyng
|
||||||
|
|
||||||
It is a common thing that occurs in many places in Lyng, function declarations,
|
It is a common thing that occurs in many places in Lyng, function declarations,
|
||||||
lambdas, struct and class declarations.
|
lambdas and class declarations.
|
||||||
|
|
||||||
## Regular
|
## Regular
|
||||||
|
|
||||||
|
@ -26,4 +26,23 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
|||||||
if( name in publicFields ) return instanceContext[name]!!.value.invoke(context, this, args)
|
if( name in publicFields ) return instanceContext[name]!!.value.invoke(context, this, args)
|
||||||
return super.invokeInstanceMethod(context, name, 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 {
|
fun testSimpleStruct() = runTest {
|
||||||
val c = Context()
|
val c = Context()
|
||||||
c.eval("""
|
c.eval("""
|
||||||
struct Point(x,y)
|
class Point(x,y)
|
||||||
assert( Point::class is Class )
|
assert( Point::class is Class )
|
||||||
val p = Point(2,3)
|
val p = Point(2,3)
|
||||||
assert(p is Point)
|
assert(p is Point)
|
||||||
@ -1405,7 +1405,7 @@ class ScriptTest {
|
|||||||
fun testNonAssignalbeFieldInStruct() = runTest {
|
fun testNonAssignalbeFieldInStruct() = runTest {
|
||||||
val c = Context()
|
val c = Context()
|
||||||
c.eval("""
|
c.eval("""
|
||||||
struct Point(x,y)
|
class Point(x,y)
|
||||||
val p = Point("2",3)
|
val p = Point("2",3)
|
||||||
assert(p is Point)
|
assert(p is Point)
|
||||||
assert( p.x == "2" )
|
assert( p.x == "2" )
|
||||||
@ -1420,7 +1420,7 @@ class ScriptTest {
|
|||||||
fun testStructBodyVal() = runTest {
|
fun testStructBodyVal() = runTest {
|
||||||
val c = Context()
|
val c = Context()
|
||||||
c.eval("""
|
c.eval("""
|
||||||
struct Point(x,y) {
|
class Point(x,y) {
|
||||||
val length = sqrt(x*x+y*y)
|
val length = sqrt(x*x+y*y)
|
||||||
var foo = "zero"
|
var foo = "zero"
|
||||||
}
|
}
|
||||||
@ -1440,7 +1440,7 @@ class ScriptTest {
|
|||||||
fun testStructBodyFun() = runTest {
|
fun testStructBodyFun() = runTest {
|
||||||
val c = Context()
|
val c = Context()
|
||||||
c.eval("""
|
c.eval("""
|
||||||
struct Point(x,y) {
|
class Point(x,y) {
|
||||||
fun length() {
|
fun length() {
|
||||||
sqrt(x*x+y*y)
|
sqrt(x*x+y*y)
|
||||||
}
|
}
|
||||||
@ -1487,4 +1487,30 @@ class ScriptTest {
|
|||||||
assertEquals( 1, cond { 1 } )
|
assertEquals( 1, cond { 1 } )
|
||||||
""".trimIndent())
|
""".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