File Coverage

blib/lib/Class/ISA.pm
Criterion Covered Total %
statement 33 37 89.1
branch 7 14 50.0
condition 1 3 33.3
subroutine 7 8 87.5
pod 3 3 100.0
total 51 65 78.4


line stmt bran cond sub pod time code
1             package Class::ISA;
2             require 5;
3 2     2   9034 use strict;
  2         5  
  2         108  
4 2     2   11 use vars qw($Debug $VERSION);
  2         4  
  2         348  
5             $VERSION = '0.36';
6             $Debug = 0 unless defined $Debug;
7              
8 2     2   2464 use if $] >= 5.011, 'deprecate';
  2         25  
  2         11  
9              
10             ###########################################################################
11              
12             sub self_and_super_versions {
13 2     2   3021 no strict 'refs';
  2         5  
  2         496  
14 0         0 map {
15 0 0   0 1 0 $_ => (defined(${"$_\::VERSION"}) ? ${"$_\::VERSION"} : undef)
  0         0  
  0         0  
16             } self_and_super_path($_[0])
17             }
18              
19             # Also consider magic like:
20             # no strict 'refs';
21             # my %class2SomeHashr =
22             # map { defined(%{"$_\::SomeHash"}) ? ($_ => \%{"$_\::SomeHash"}) : () }
23             # Class::ISA::self_and_super_path($class);
24             # to get a hash of refs to all the defined (and non-empty) hashes in
25             # $class and its superclasses.
26             #
27             # Or even consider this incantation for doing something like hash-data
28             # inheritance:
29             # no strict 'refs';
30             # %union_hash =
31             # map { defined(%{"$_\::SomeHash"}) ? %{"$_\::SomeHash"}) : () }
32             # reverse(Class::ISA::self_and_super_path($class));
33             # Consider that reverse() is necessary because with
34             # %foo = ('a', 'wun', 'b', 'tiw', 'a', 'foist');
35             # $foo{'a'} is 'foist', not 'wun'.
36              
37             ###########################################################################
38             sub super_path {
39 1     1 1 642 my @ret = &self_and_super_path(@_);
40 1 50       5 shift @ret if @ret;
41 1         6 return @ret;
42             }
43              
44             #--------------------------------------------------------------------------
45             sub self_and_super_path {
46             # Assumption: searching is depth-first.
47             # Assumption: '' (empty string) can't be a class package name.
48             # Note: 'UNIVERSAL' is not given any special treatment.
49 1 50   1 1 5 return () unless @_;
50              
51 1         2 my @out = ();
52              
53 1         4 my @in_stack = ($_[0]);
54 1         2 my %seen = ($_[0] => 1);
55              
56 1         3 my $current;
57 1         5 while(@in_stack) {
58 7 50 33     39 next unless defined($current = shift @in_stack) && length($current);
59 7 50       16 print "At $current\n" if $Debug;
60 7         14 push @out, $current;
61 2     2   11 no strict 'refs';
  2         4  
  2         278  
62 8         13 unshift @in_stack,
63             map
64 7         24 { my $c = $_; # copy, to avoid being destructive
65 8 50       22 substr($c,0,2) = "main::" if substr($c,0,2) eq '::';
66             # Canonize the :: -> main::, ::foo -> main::foo thing.
67             # Should I ever canonize the Foo'Bar = Foo::Bar thing?
68 8 100       39 $seen{$c}++ ? () : $c;
69             }
70 7         8 @{"$current\::ISA"}
71             ;
72             # I.e., if this class has any parents (at least, ones I've never seen
73             # before), push them, in order, onto the stack of classes I need to
74             # explore.
75             }
76              
77 1         8 return @out;
78             }
79             #--------------------------------------------------------------------------
80             1;
81              
82             __END__