Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you show the type hierarchy of a value?

Tags:

raku

mop

In Perl5 and Moose, linear isa or linearized isa helps make sense of class hierarchies.

The method WHAT shows the concrete type of a value:

> 42.WHAT
(Int)

How do I show something like

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

… possibly with further lines for each consumed role?


edit: example with two strands of roles

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‽
like image 369
daxim Avatar asked May 30 '17 06:05

daxim


1 Answers

You can query the meta object with

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

where mro stand for method resolution order and

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

You can control which roles are returned via the adverbs :local (exlude roles inherited from parent classes - only available on classes) and :!transitive (exclude roles composed via another role - available on both roles and classes).


The following should get you started:

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));
}

Given your example code with slight 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 {}

it produces the output

is Alpha
  does Epsilon
    does Zeta
      does Eta
  does Gamma
    does Delta
is Beta
  does Gamma
    does Delta
is Any
is Mu
like image 102
Christoph Avatar answered Nov 08 '22 21:11

Christoph