File Coverage

blib/lib/Rose/HTML/Object/Exporter.pm
Criterion Covered Total %
statement 59 88 67.0
branch 18 44 40.9
condition 11 32 34.3
subroutine 12 14 85.7
pod 0 6 0.0
total 100 184 54.3


line stmt bran cond sub pod time code
1              
2             use strict;
3 47     47   323  
  47         81  
  47         1133  
4             use Carp;
5 47     47   192  
  47         78  
  47         5246  
6             our $VERSION = '0.605';
7              
8             our $Debug = 0;
9              
10             use Rose::Class::MakeMethods::Generic
11             (
12             inheritable_hash =>
13 47         637 [
14             export_tags => { interface => 'get_set_all', hash_key => 'export_tags' },
15             _export_tag => { interface => 'get_set', hash_key => 'export_tags' },
16             clear_export_tags => { interface => 'clear', hash_key => 'export_tags' },
17             delete_export_tags => { interface => 'delete', hash_key => 'export_tags' },
18              
19             _pre_import_hooks => { interface => 'get_set_all', hash_key => 'pre_import_hooks' },
20             _pre_import_hook => { interface => 'get_set', hash_key => 'pre_import_hooks' },
21             clear_pre_import_hooks => { interface => 'clear', hash_key => 'pre_import_hooks' },
22             delete_pre_import_hooks => { interface => 'delete', hash_key => 'pre_import_hooks' },
23             ],
24             );
25 47     47   22030  
  47         317626  
26             our %Imported;
27              
28             {
29             my($class, $symbol) = (shift, shift);
30              
31 3780     3780 0 5380 if(@_)
32             {
33 3780 50       6026 return $Imported{$class}{$symbol}{'from'} = shift;
34             }
35 0         0  
36             return $Imported{$class}{$symbol};
37             }
38 3780         8026  
39             our $Target_Class;
40              
41             {
42             my($class) = shift;
43              
44             my $target_class = $Target_Class || (caller)[0];
45 332     332   609  
46             my($force, @symbols, %import_as, $imported);
47 332   33     817  
48             foreach my $arg (@_)
49 332         615 {
50             if($arg =~ /^-?-force$/)
51 332         708 {
52             $force = 1;
53 344 50       1966 }
    100          
    50          
54             elsif($arg =~ /^:(.+)/)
55 0         0 {
56             my $symbols = $class->export_tag($1) or
57             croak "Unknown export tag - '$arg'";
58              
59 232 50       928 push(@symbols, @$symbols);
60             }
61             elsif(ref $arg eq 'HASH')
62 232         884 {
63             while(my($symbol, $name) = each(%$arg))
64             {
65             push(@symbols, $symbol);
66 0         0 $import_as{$symbol} = $name;
67             }
68 0         0 }
69 0         0 else
70             {
71             push(@symbols, $arg);
72             }
73             }
74 112         305  
75             foreach my $symbol (@symbols)
76             {
77             my $code = $class->can($symbol) or
78 332         728 croak "Could not import symbol '$symbol' from $class into $target_class - no such symbol";
79              
80 2831 50       9364 my $is_constant = (defined prototype($code) && !length(prototype($code))) ? 1 : 0;
81              
82             my $import_as = $import_as{$symbol} || $symbol;
83 2831 50 33     9601  
84             my $existing_code = $target_class->can($import_as);
85 2831   33     7035  
86             no strict 'refs';
87 2831         11633 no warnings 'uninitialized';
88              
89 47     47   38652 if($existing_code && !$force && (
  47         111  
  47         2860  
90 47     47   293 ($is_constant && $existing_code eq \&{"${target_class}::$import_as"}) ||
  47         86  
  47         9057  
91             (!$is_constant && $existing_code)))
92 2831 50 66     5965 {
      33        
      66        
93             next if($Imported{$target_class}{$import_as});
94              
95             croak "Could not import symbol '$import_as' from $class into ",
96 299 50       1165 "$target_class - a symbol by that name already exists. ",
97             "Pass a '--force' argument to import() to override ",
98 0         0 "existing symbols."
99             }
100              
101             if(my $hooks = $class->pre_import_hooks($symbol))
102             {
103             foreach my $code (@$hooks)
104 2532 50       4221 {
105             my $error;
106 2532         4009  
107             TRY:
108 0         0 {
109             local $@;
110             eval { $code->($class, $symbol, $target_class, $import_as) };
111             $error = $@;
112 0         0 }
  0         0  
113 0         0  
  0         0  
114 0         0 if($error)
115             {
116             croak "Could not import symbol '$import_as' from $class into ",
117 0 0       0 "$target_class - $error";
118             }
119 0         0 }
120             }
121              
122             if($is_constant)
123             {
124             no strict 'refs';
125 2532 50       3698 $Debug && warn "${target_class}::$import_as = ${class}::$symbol\n";
126             *{$target_class . '::' . $import_as} = *{"${class}::$symbol"};
127 47     47   458 }
  47         1514  
  47         3375  
128 2532 50       3726 else
129 2532         2764 {
  2532         6539  
  2532         6136  
130             no strict 'refs';
131             $Debug && warn "${target_class}::$import_as = ${class}->$symbol\n";
132             *{$target_class . '::' . $import_as} = $code;
133 47     47   296 }
  47         89  
  47         24187  
134 0 0       0  
135 0         0 $Imported{$target_class}{$import_as}{'from'} = $class;
  0         0  
136             }
137             }
138 2532         26513  
139             {
140             my($class, $tag) = (shift, shift);
141              
142             if(index($tag, ':') == 0)
143             {
144 232     232 0 1017 croak 'Tag name arguments to export_tag() should not begin with ":"';
145             }
146 232 50       743  
147             if(@_ && (@_ > 1 || (ref $_[0] || '') ne 'ARRAY'))
148 0         0 {
149             croak 'export_tag() expects either a single tag name argument, ',
150             'or a tag name and a reference to an array of symbol names';
151 232 0 0     510 }
      33        
152              
153 0         0 my $ret = $class->_export_tag($tag, @_);
154              
155             croak "No such tag: $tag" unless($ret);
156              
157 232         872 return wantarray ? @$ret : $ret;
158             }
159 232 50       3330  
160             {
161 232 50       774 my($class) = shift;
162              
163             while(@_)
164             {
165             my($tag, $arg) = (shift, shift);
166 0     0 0 0 $class->export_tag($tag, $arg);
167             }
168 0         0 }
169              
170 0         0 {
171 0         0 my($class, $tag) = (shift, shift);
172             my $list = $class->export_tag($tag);
173             push(@$list, @_);
174             }
175              
176             *delete_export_tag = \&delete_export_tags;
177 0     0 0 0  
178 0         0 {
179 0         0 my($class, $symbol) = (shift, shift);
180              
181             if(@_ && (@_ > 1 || (ref $_[0] && (ref $_[0] || '') !~ /\A(?:ARRAY|CODE)\z/)))
182             {
183             croak 'pre_import_hook() expects either a single symbol name argument, ',
184             'or a symbol name and a code reference or a reference to an array ',
185             'of code references';
186 2532     2532 0 3880 }
187              
188 2532 0 0     5029 if(@_)
      33        
189             {
190 0         0 unless(ref $_[0] eq 'ARRAY')
191             {
192             $_[0] = [ $_[0] ];
193             }
194             }
195 2532 50       3770  
196             my $ret = $class->_pre_import_hook($symbol, @_) || [];
197 0 0       0  
198             return wantarray ? @$ret : $ret;
199 0         0 }
200              
201              
202             *delete_pre_import_hook = \&delete_pre_import_hooks;
203 2532   50     5030  
204             1;