strange behavior when including multiple times startsub parts

0 votes
asked Aug 3, 2020 in Bug by anonymous

Taking this small example to illustrate my problem.

common.puml

@startuml common

!startsub COMMON

abstract Common {
    id : uuid
}

!endsub

@enduml

myclass1.puml

@startuml myclass1

!includesub common.puml!COMMON

class MyClass1 extends Common {
    text: string
}

@enduml

myclass2.puml

@startuml myclass1

!includesub common.puml!COMMON

class MyClass2 extends Common {
    value: int
}

@enduml

all.puml

@startuml all

!include ./sub/common.puml
!include ./sub/myclass1.puml
!include ./sub/myclass2.puml

@enduml

When redering the all.puml diagram, I have a strange result in the Common part. Attributes are rendered 3 times !

enter image description here

Any idea ?

commented Aug 3, 2020 by anonymous

I use !includesub to add some objects that are in other files.

If I don't use the !includesub, I can not renderer the myclass1.puml and myclass2.puml independently (I will only have the Common object but without attributes and class type).

Is there a possibility to test if an object is already present ?

Such like this :

if not exists(COMMON )

  !includesub common.puml!COMMON

endif

commented Aug 3, 2020 by Martin

It's worth noting that you can simulate it in a single diagram as follows:

@startuml
abstract Common {
    id : uuid
}
abstract Common {
    id : uuid
}
abstract Common {
    id : uuid
}
class MyClass1 extends Common {
    text: string
}
class MyClass2 extends Common {
    value: int
}
@enduml

http://www.plantuml.com/plantuml/png/SoWkIImgAStDuKfCAYufIamkKN3EpytDprEevb80WimK1Ik5qjBC5AvQggX8paaiBbRmhNG6qOOAgHKbgNafnQZgIu2YLWf0apBpqj6r667NKfQOKvfgfP2PLmBKu02K1_e80000

(so removing "!includesub common.puml!COMMON" from your two class pumls would be a workaround, but I can see why you would want them there.)

commented Aug 3, 2020 by anonymous
I want also to generate the diagrams for myclass1.puml and myclass2.puml separately. If I remove the !includesub, I will loose what Common represent.
commented Aug 4, 2020 by anonymous

One solution I found, is :

Common.puml

@startuml common

!startsub COMMON

abstract Common {
    id : uuid
}
!$COMMON_EXISTS = ""
!endsub

@enduml

MyClass1.puml

@startuml myclass1

!if %not(%variable_exists("$COMMON_EXISTS"))
    !includesub common.puml!COMMON
!endif

class MyClass1 extends Common {
    text: string
}

@enduml

MyClass2.puml

@startuml myclass2

!if %not(%variable_exists("$COMMON_EXISTS"))
    !includesub common.puml!COMMON
!endif

class MyClass2 extends Common {
    value: int
}

@enduml

1 Answer

0 votes
answered Aug 3, 2020 by Martin

So your observation is that !includesub works like !include_many rather than !include.  @plantuml could consider ignoring duplicate subparts in the same way they ignore duplicate whole files.

But as was suggested in the comments above, a workaround is to detect if common is already loaded.  The following common.puml seems to do what you want (I used "!else" because I wasn't sure the syntax for "not"):

@startuml common
!startsub COMMON
!if (%variable_exists("$common"))
!else
!$common = true
abstract Common {
    id : uuid
}
!endif
!endsub
@enduml

commented Aug 4, 2020 by anonymous

This is what I finally done :

Common.puml

@startuml common

!startsub COMMON
    !if %not(%variable_exists("$COMMON_EXISTS"))
        abstract Common {
            id : uuid
        }
        !$COMMON_EXISTS = true
    !endif
!endsub

@enduml

MyClass1.puml

@startuml myclass1

!includesub common.puml!COMMON

class MyClass1 extends Common {
    text: string
}

@enduml

MyClass2.puml

@startuml myclass2

!includesub common.puml!COMMON

class MyClass2 extends Common {
    value: int
}

@enduml

Would be nice to have the possibility to check if an object exists or not.

    !if %not(%object_exists("$Common"))

...