/
Object.pm
75 lines (70 loc) · 2.59 KB
/
Object.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
subset Matcher of Object where { .can('ACCEPTS') };
class Object is also {
multi method perl {
self.WHAT.substr(0, -2) ~ '.new()';
}
multi method eigenstates {
list(self)
}
method WALK(:$name!, :$canonical, :$ascendant, :$descendant, :$preorder, :$breadth,
:$super, Matcher :$omit = False, Matcher :$include = True) {
# First, build list of classes in the order we'll need them.
my @classes;
if $super {
@classes = self.^parents(:local);
} else {
if $breadth {
my @search_list = self.WHAT;
while @search_list {
push @classes, @search_list.list();
my @new_search_list;
for @search_list -> $current {
for $current.^parents(:local) -> $next {
unless any(@new_search_list <<===>> $next) {
push @new_search_list, $next;
}
}
}
@search_list = @new_search_list;
}
} elsif $ascendant | $preorder {
my sub build_ascendent($class) {
unless any(@classes <<===>> $class) {
push @classes, $class;
for $class.^parents(:local) {
build_ascendent($^parent);
}
}
}
build_ascendent(self.WHAT);
} elsif $descendant {
my sub build_descendent($class) {
unless any(@classes <<===>> $class) {
for $class.^parents(:local) {
build_descendent($^parent);
}
push @classes, $class;
}
}
build_descendent(self.WHAT);
} else {
# Canonical, the default (just whatever the meta-class says).
@classes = self.^parents();
}
}
# Now we have classes, build method list.
my @methods;
for @classes -> $class {
if $include.ACCEPTS($class) && !$omit.ACCEPTS($class) {
for $class.^methods() -> $method {
my $check_name = $method.?name;
if $check_name.defined && $check_name eq $name {
@methods.push($method);
}
}
}
}
return @methods;
}
}
# vim: ft=perl6