File Coverage

blib/lib/Astro/App/Satpass2/Macro/Code.pm
Criterion Covered Total %
statement 27 53 50.9
branch 2 16 12.5
condition 2 6 33.3
subroutine 8 12 66.6
pod 5 5 100.0
total 44 92 47.8


line stmt bran cond sub pod time code
1             package Astro::App::Satpass2::Macro::Code;
2              
3 20     20   348 use 5.008;
  20         76  
4              
5 20     20   191 use strict;
  20         63  
  20         531  
6 20     20   105 use warnings;
  20         36  
  20         1297  
7              
8 20     20   108 use parent qw{ Astro::App::Satpass2::Macro };
  20         37  
  20         117  
9              
10 20         2641 use Astro::App::Satpass2::Utils qw{
11             expand_tilde
12             load_package
13             quoter
14             @CARP_NOT
15 20     20   1810 };
  20         45  
16 20     20   142 use File::Spec;
  20         68  
  20         6100  
17              
18             our $VERSION = '0.057';
19              
20             sub init {
21 1     1 1 3 my ( $self ) = @_;
22 1         9 $self->SUPER::init();
23 1         8 my $parent = $self->parent();
24 1         6 my %popt = ( complaint => 'wail', fatal => 'wail' );
25             exists $self->{lib}
26 1 50       9 and $popt{lib} = $self->expand_tilde( $self->{lib} );
27             defined $self->{lib}
28             and not $self->{relative}
29             and not $self->{lib} =~ m/ \A ~ /smx
30 1 50 33     25 and $self->{lib} = File::Spec->rel2abs( $self->{lib} );
      33        
31 1         11 my $module = $self->load_package(
32             \%popt, $self->name(), 'Astro::App::Satpass2::Macro::Code'
33             );
34 0 0         $module->isa( 'Astro::App::Satpass2' )
35             or $self->wail( "$module is not a subclass of Astro::App::Satpass2" );
36              
37 0           my %implements; # Names and references to found code
38 0           my $stb = "${module}::"; # Name of loaded symbol table
39              
40             # Fairly deep magic begins here. We need symbolic references to
41             # traverse the symbol table of the loaded code, so:
42 20     20   165 no strict qw{ refs };
  20         41  
  20         10774  
43              
44 0           foreach my $name ( keys %$stb ) {
45 0           my $val = $stb->{$name};
46              
47             # We are only interested in symbols that start with alphabetics.
48 0 0         $name =~ m/ \A [[:alpha:]] /smx
49             or next;
50              
51             # We do not want symbols unless they contain at least one
52             # lower-case character.
53 0 0         $name =~ m/ [[:lower:]] /smx
54             or next;
55              
56             # We need a reference to the entry's glob, which we obtain by
57             # symbolic reference.
58 0           my $glob = \$val;
59              
60             # If $name refers to an inlineable function, $val is going to be
61             # its value. This is not what we want, so ...
62 0 0         'GLOB' eq ref $glob
63             or next;
64              
65             # If the code slot is empty we ignore it.
66 0           *{$glob}{CODE}
67 0 0         or next;
68              
69             # If the code does not have the Verb() attribute, we ignore it.
70             # TODO technically we have an encapsulation failure here which
71             # needs to be fixed up.
72 0 0         $parent->__get_attr( *{$glob}{CODE}, 'Verb' )
  0            
73             or next;
74              
75             # Record the fact that the module defines this name.
76 0           $implements{$name} = *{$glob}{CODE};
  0            
77             }
78              
79             # End of symbol table magic.
80 0           $self->{implements} = \%implements;
81 0           return;
82             }
83              
84             sub execute {
85 0     0 1   my ( $self, $name, @args ) = @_;
86 0           my $code = $self->implements( $name, required => 1 );
87 0           return $code->( $self->parent(), @args );
88             }
89              
90             sub has_lib {
91 0     0 1   my ( $self ) = @_;
92 0           return exists $self->{lib};
93             }
94              
95             sub lib {
96 0     0 1   my ( $self ) = @_;
97 0           return $self->{lib};
98             }
99              
100             sub relative {
101 0     0 1   my ( $self ) = @_;
102 0           return $self->{relative};
103             }
104              
105             1;
106              
107             __END__