From be370dfdef94f7fc89fd1216c0e285b7a897d596 Mon Sep 17 00:00:00 2001 From: sergeych Date: Wed, 6 Aug 2025 23:10:02 +0300 Subject: [PATCH] fix #45 private statics and docs --- docs/OOP.md | 43 ++++++++++++++++++- .../kotlin/net/sergeych/lyng/obj/ObjClass.kt | 8 ++-- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/docs/OOP.md b/docs/OOP.md index b6320b4..a958930 100644 --- a/docs/OOP.md +++ b/docs/OOP.md @@ -147,7 +147,7 @@ In many cases it is necessary to implement custom comparison and `toString`, sti 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. +- default comparison compares all fields in order of appearance. For example, for our class Point: @@ -160,6 +160,47 @@ For example, for our class Point: Point(1,1+1) >>> Point(x=1,y=2) +## Statics: class fields and class methods + +You can mark a field or a method as static. This is borrowed from Java as more plain version of a kotlin's companion object or Scala's object. Static field and functions is one for a class, not for an instance. From inside the class, e.g. from the class method, it is a regular var. From outside, it is accessible as `ClassName.field` or method: + + + class Value(x) { + static var foo = Value("foo") + + static fun exclamation() { + // here foo is a regular var: + foo.x + "!" + } + } + assertEquals( Value.foo.x, "foo" ) + assertEquals( "foo!", Value.exclamation() ) + + // we can access foo from outside like this: + Value.foo = Value("bar") + assertEquals( "bar!", Value.exclamation() ) + >>> void + +As usual, private statics are not accessible from the outside: + + class Test { + // private, inacessible from outside protected data: + private static var data = null + + // the interface to access and change it: + static fun getData() { data } + static fun setData(value) { data = value } + } + + // no direct access: + assertThrows { Test.data } + + // accessible with the interface: + assertEquals( null, Test.getData() ) + Test.setData("fubar") + assertEquals("fubar", Test.getData() ) + >>> void + # Extending classes It sometimes happen that the class is missing some particular functionality that can be _added to it_ without rewriting its inner logic and using its private state. In this case _extension methods_ could be used, for example. we want to create an extension method diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjClass.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjClass.kt index 4d658a0..8e395e2 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjClass.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjClass.kt @@ -110,17 +110,17 @@ open class ObjClass( override suspend fun readField(scope: Scope, name: String): ObjRecord { classScope?.objects?.get(name)?.let { - return it + if( it.visibility.isPublic ) return it } return super.readField(scope, name) } - override suspend fun writeField(scope: Scope, name: String, value: Obj) { + override suspend fun writeField(scope: Scope, name: String, newValue: Obj) { initClassScope().objects[name]?.let { - if( it.isMutable) it.value = value + if( it.isMutable) it.value = newValue else scope.raiseIllegalAssignment("can't assign $name is not mutable") } - ?: super.writeField(scope, name, value) + ?: super.writeField(scope, name, newValue) } override suspend fun invokeInstanceMethod(scope: Scope, name: String, args: Arguments,