2017-05-30 7 views
7

En Perl5 et Moose, linéaire isa ou linéarisé isa permet de donner un sens aux hiérarchies de classes.Comment afficher la hiérarchie de type d'une valeur?

La méthode WHAT indique le type de béton d'une valeur:

> 42.WHAT 
(Int) 

Comment puis-je montrer quelque chose comme

> 42.hypothetical-type-hierarchy 
(Int) ┬ is (Cool) ─ is (Any) ─ is (Mu) 
     └ does (Real) ─ does (Numeric) 

... peut-être avec des lignes supplémentaires pour chaque rôle consommé?


edit: par exemple avec deux brins de rôles

class Beta {} 
role Delta {} 
role Gamma does Delta {} 
role Eta {} 
role Zeta does Eta {} 
role Epsilon does Zeta {} 
class Alpha is Beta does Gamma does Epsilon {} 

# (Alpha) ┬ is (Beta) 
#   ├ does (Gamma) ─ does (Delta) 
#   └ does (Epsilon) ─ does (Zeta) ─ does (Eta) 

my $ai = Alpha.new 
$ai.^mro  # ((Alpha) (Beta) (Any) (Mu)) 

$ai.^roles  # ((Epsilon) (Zeta) (Eta) (Gamma) (Delta)) 
       # flat list, not two-element list of a tuple and triple‽ 
+1

'.WHAT' doesn 't _show_ anything, il vous donne l'objet type. Ce qui pour les types qui n'ont pas de '::' dans '' .gist' dans quelque chose de raisonnable. Vous devriez vraiment appeler '.^Nom'. –

Répondre

8

Vous pouvez interroger l'objet méta avec

> 42.^mro 
((Int) (Cool) (Any) (Mu)) 

mro position pour la résolution méthode pour et

> 42.^roles 
((Real) (Numeric)) 

Vous pouvez contrôler quels rôles sont renvoyés via les adverbes :local (exclure les rôles hérités des classes parentes - disponibles uniquement sur les classes) et :!transitive (exclure les rôles composés via un autre rôle - disponibles sur les rôles et les classes).


Ce qui suit devrait vous aider à démarrer:

my $depth = 0; 
for Alpha.^mro { 
    say "is {.^name}"; 
    (sub { 
     ++$depth; 
     for @_ { 
      say ' ' x $depth ~ "does {.^name}"; 
      &?ROUTINE(.^roles(:!transitive)); # recursive call of anon sub 
     } 
     --$depth; 
    })(.^roles(:local, :!transitive)); 
} 

Compte tenu de votre code d'exemple avec de légères modifications

role Delta {} 
role Gamma does Delta {} 
role Eta {} 
role Zeta does Eta {} 
role Epsilon does Zeta {} 
class Beta does Gamma {} 
class Alpha is Beta does Gamma does Epsilon {} 

il produit la sortie

is Alpha 
    does Epsilon 
    does Zeta 
     does Eta 
    does Gamma 
    does Delta 
is Beta 
    does Gamma 
    does Delta 
is Any 
is Mu 
+0

Désolé, je ne comprends pas la partie adverbe. Pouvez-vous illustrer avec le deuxième exemple dans mon post édité? – daxim

+1

@daxim Un [adverbe] (https://docs.perl6.org/language/glossary#Adverb) est un argument nommé qui modifie ce qu'une fonction fait. Par exemple, passer ':! Transitive' supprime les rôles' do'd [transitif] (http://www.dictionary.com/browse/transitively). (Le '!' Signifie "non", ie ':! Transitive' est analogue à l'expression adverbiale anglaise" non transitif ".) Donc' say $ ai.^Roles (:! Transitive) 'avec votre code affiche juste' ((Epsilon) (Gamma)). – raiph

+1

Cela ressemble à un module utilitaire agréable dans l'écosystème. * indice * * indice * :-) –