Reputation: 736
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.)
Meta-programming: what, why and how (perl6advent)
Day 19 – Introspection (perl6advent)
How do I access a module's symbol table dynamically at runtime in Raku? (stackoverflow)
Is there a way to get a list of all known types in a Perl 6 program? (stackoverflow)
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:
Design parser(s) of the code of classes in software packages made with languages like C++, Java, Kotlin, Raku
Generate the corresponding PlantUML code over the parsing results
(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
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
Upvotes: 1
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