Anton Antonov
Anton Antonov

Reputation: 736

Find programmatically all classes, grammars, and roles in a Raku package

How can I find programmatically all the classes, grammars, and roles in a Raku package? (Specified with a string.)

I examined discussions/posts similar to the ones linked below, but the code I came up with is very hard to use. (And does not do the job.)

Motivation

I would like to automatically generate UML class diagrams for Raku packages.

See the PlantUML diagrams for the Raku package: ML::StreamsBlendingRecommender.

I considered the steps:

(Such parsers might not be that hard to derive. Probably, the work of DrForr provides good starts.)

But given Raku's introspection abilities, instead of parsing Raku code I should be able to "just" traverse package namespaces and classes. (Instead of making a parser.)

Upvotes: 8

Views: 260

Answers (2)

Anton Antonov
Anton Antonov

Reputation: 736

The question :

How can I find programmatically all the classes, grammars, and roles in a Raku package? (Specified with a string.)

is answered with the package UML::Translators.

For example,

.say for get-namespace-classes( 'ML::TriesWithFrequencies' ).map({ $_ ~~ Str ?? $_ !! $_.^name }).sort

# ML::TriesWithFrequencies::LeafProbabilitiesGatherer
# ML::TriesWithFrequencies::ParetoBasedRemover
# ML::TriesWithFrequencies::PathsGatherer
# ML::TriesWithFrequencies::RegexBasedRemover
# ML::TriesWithFrequencies::ThresholdBasedRemover
# ML::TriesWithFrequencies::Trie
# ML::TriesWithFrequencies::TrieTraverse
# ML::TriesWithFrequencies::Trieish
# TRIEROOT
# TRIEVALUE

The package provides the Command Line Interface (CLI) script to-uml-spec that can be used to generate UML specs with the PlantUML domain specific language. Here is an example:

to-uml-spec --/methods --/attributes 'Chemistry::Stoichiometry'
@startuml
class Chemistry::Stoichiometry::Grammar <<grammar>> {
}
Chemistry::Stoichiometry::Grammar --|> Grammar
Chemistry::Stoichiometry::Grammar --|> Match
Chemistry::Stoichiometry::Grammar --|> Capture
Chemistry::Stoichiometry::Grammar --|> Chemistry::Stoichiometry::Grammar::ChemicalElement
Chemistry::Stoichiometry::Grammar --|> Chemistry::Stoichiometry::Grammar::ChemicalEquation
Chemistry::Stoichiometry::Grammar --|> NQPMatchRole


class Chemistry::Stoichiometry::ResourceAccess  {
}


class Chemistry::Stoichiometry::Actions::MolecularMass  {
}


class Chemistry::Stoichiometry::Actions::EquationMatrix  {
}


class Chemistry::Stoichiometry::Actions::EquationBalance  {
}
Chemistry::Stoichiometry::Actions::EquationBalance --|> Chemistry::Stoichiometry::Actions::EquationMatrix


class Chemistry::Stoichiometry::Actions::WL::System  {
}


@enduml

Using CLI and a PlantUML JAR file we can generate UML diagrams like this:

to-uml-spec --/methods --/attributes 'Chemistry::Stoichiometry' | java -jar ~/Downloads/plantuml-1.2022.5.jar -pipe -tjpg > /tmp/myuml.jpg

enter image description here

Upvotes: 1

Elizabeth Mattijsen
Elizabeth Mattijsen

Reputation: 26979

There is no "central" dictionary of classes in Raku. And making the question even harder to solve, classes only now about their parent classes and roles they consume. But they do not know about any classes that inherit from them. Or if you look at a role, which other roles and classes consume that role.

Classes and roles in Raku are therefore irresponsible parents :-)

I guess there could be a way to do some trickery in the MOP, but that could have significant performance effects and cause memory leaks (as many temporary classes wouldn't be garbage collected anymore, because the record keeping would keep it alive).

Upvotes: 6

Related Questions