This message was deleted.
# getting-started
s
This message was deleted.
p
inheritance across singletons sounds like sort of an anti-pattern; I could see singletons implementing an interface but I don’t know why you wouldn’t just reference A, B, C individually here
y
Have them be `open class`es with each companion just simply extending its surrounding class without adding anything extra
e
Copy code
sealed class A {
    val a = "..."
    companion object : A()
}
sealed class B : A() {
    val b = "..."
    companion object : B()
}
sealed class C : B() {
    val c = "..."
    companion object : C()
}
but I agree with above, this does not seem like a great pattern
🤔 1
🙌 2
y
Maybe consider if context receivers could work here? If you don't have any actual polymorphism (functions overriding parent functions, or functions changing behaviour based on the object) then using a bunch of context receivers could be more elegant
👍 1
For instance, I'm fiddling with a weird DSL myself currently and I use context receivers to bring a few methods into certain scopes. The usual alternative would be to subclass my DSL class and add those extra methods, but having those methods on a context receiver helps out a lot. What I do is define a new (maybe value) class
MyExtra
and I add the methods I want as extensions on MyExtra but while requiring a context of the normal DSL class. Then simply whenever I want to give the user access to those methods, I put them in a
context(DslClass, MyExtra)
and let the magic happen
e
it's not obvious to me those need to be
object
, and even plain old receivers may work if you have a simple setup, e.g.
Copy code
interface A { companion object }
val A.a get() = ...
interface B : A { companion object }
val B.b get() = ...
interface C : B { companion object }
val C.c get() = ...
y
What I was thinking is you can define classes with the attributes you want the user to provide e.g. header, sponsor-width, etc.and have the objects implement defaults for it. What you can then do is if the user wants to implement their own custom properties they can simply create a class for that, and you, as the library, just takes the user's custom type and passes it along as an extra context to the dsl calls, meaning that instead of inheritance, you use composition. TBH, now that I think about it more, it is more of a superficial difference, so as long as your Dsl design is working so far, then just carry on. I'd be interested to look through your library if you ever publish it on github btw, sounds like there's a lot of room to use some slick DSL tricks with delegates for instance (btw, did you know that local delegated variables can use context receivers? it's a very neat feature and it could help you out here.)