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             package Rose::HTML::Object::Exporter;
2              
3 47     47   393 use strict;
  47         109  
  47         1332  
4              
5 47     47   232 use Carp;
  47         116  
  47         6404  
6              
7             our $VERSION = '0.605';
8              
9             our $Debug = 0;
10              
11             use Rose::Class::MakeMethods::Generic
12             (
13 47         738 inheritable_hash =>
14             [
15             export_tags => { interface => 'get_set_all', hash_key => 'export_tags' },
16             _export_tag => { interface => 'get_set', hash_key => 'export_tags' },
17             clear_export_tags => { interface => 'clear', hash_key => 'export_tags' },
18             delete_export_tags => { interface => 'delete', hash_key => 'export_tags' },
19              
20             _pre_import_hooks => { interface => 'get_set_all', hash_key => 'pre_import_hooks' },
21             _pre_import_hook => { interface => 'get_set', hash_key => 'pre_import_hooks' },
22             clear_pre_import_hooks => { interface => 'clear', hash_key => 'pre_import_hooks' },
23             delete_pre_import_hooks => { interface => 'delete', hash_key => 'pre_import_hooks' },
24             ],
25 47     47   28458 );
  47         378498  
26              
27             our %Imported;
28              
29             sub imported
30             {
31 3779     3779 0 6553 my($class, $symbol) = (shift, shift);
32              
33 3779 50       7082 if(@_)
34             {
35 0         0 return $Imported{$class}{$symbol}{'from'} = shift;
36             }
37              
38 3779         9755 return $Imported{$class}{$symbol};
39             }
40              
41             our $Target_Class;
42              
43             sub import
44             {
45 332     332   731 my($class) = shift;
46              
47 332   33     930 my $target_class = $Target_Class || (caller)[0];
48              
49 332         739 my($force, @symbols, %import_as, $imported);
50              
51 332         815 foreach my $arg (@_)
52             {
53 344 50       2350 if($arg =~ /^-?-force$/)
    100          
    50          
54             {
55 0         0 $force = 1;
56             }
57             elsif($arg =~ /^:(.+)/)
58             {
59 232 50       1108 my $symbols = $class->export_tag($1) or
60             croak "Unknown export tag - '$arg'";
61              
62 232         1049 push(@symbols, @$symbols);
63             }
64             elsif(ref $arg eq 'HASH')
65             {
66 0         0 while(my($symbol, $name) = each(%$arg))
67             {
68 0         0 push(@symbols, $symbol);
69 0         0 $import_as{$symbol} = $name;
70             }
71             }
72             else
73             {
74 112         321 push(@symbols, $arg);
75             }
76             }
77              
78 332         803 foreach my $symbol (@symbols)
79             {
80 2831 50       12092 my $code = $class->can($symbol) or
81             croak "Could not import symbol '$symbol' from $class into $target_class - no such symbol";
82              
83 2831 50 33     11590 my $is_constant = (defined prototype($code) && !length(prototype($code))) ? 1 : 0;
84              
85 2831   33     8344 my $import_as = $import_as{$symbol} || $symbol;
86              
87 2831         15818 my $existing_code = $target_class->can($import_as);
88              
89 47     47   45882 no strict 'refs';
  47         142  
  47         3674  
90 47     47   369 no warnings 'uninitialized';
  47         129  
  47         10506  
91              
92 2831 50 66     7250 if($existing_code && !$force && (
      33        
      66        
93             ($is_constant && $existing_code eq \&{"${target_class}::$import_as"}) ||
94             (!$is_constant && $existing_code)))
95             {
96 299 50       2334 next if($Imported{$target_class}{$import_as});
97              
98 0         0 croak "Could not import symbol '$import_as' from $class into ",
99             "$target_class - a symbol by that name already exists. ",
100             "Pass a '--force' argument to import() to override ",
101             "existing symbols."
102             }
103              
104 2532 50       5160 if(my $hooks = $class->pre_import_hooks($symbol))
105             {
106 2532         4808 foreach my $code (@$hooks)
107             {
108 0         0 my $error;
109              
110             TRY:
111             {
112 0         0 local $@;
  0         0  
113 0         0 eval { $code->($class, $symbol, $target_class, $import_as) };
  0         0  
114 0         0 $error = $@;
115             }
116              
117 0 0       0 if($error)
118             {
119 0         0 croak "Could not import symbol '$import_as' from $class into ",
120             "$target_class - $error";
121             }
122             }
123             }
124              
125 2532 50       4416 if($is_constant)
126             {
127 47     47   442 no strict 'refs';
  47         1955  
  47         3939  
128 2532 50       4577 $Debug && warn "${target_class}::$import_as = ${class}::$symbol\n";
129 2532         3330 *{$target_class . '::' . $import_as} = *{"${class}::$symbol"};
  2532         8444  
  2532         7680  
130             }
131             else
132             {
133 47     47   372 no strict 'refs';
  47         128  
  47         29260  
134 0 0       0 $Debug && warn "${target_class}::$import_as = ${class}->$symbol\n";
135 0         0 *{$target_class . '::' . $import_as} = $code;
  0         0  
136             }
137              
138 2532         30240 $Imported{$target_class}{$import_as}{'from'} = $class;
139             }
140             }
141              
142             sub export_tag
143             {
144 232     232 0 1098 my($class, $tag) = (shift, shift);
145              
146 232 50       983 if(index($tag, ':') == 0)
147             {
148 0         0 croak 'Tag name arguments to export_tag() should not begin with ":"';
149             }
150              
151 232 0 0     622 if(@_ && (@_ > 1 || (ref $_[0] || '') ne 'ARRAY'))
      33        
152             {
153 0         0 croak 'export_tag() expects either a single tag name argument, ',
154             'or a tag name and a reference to an array of symbol names';
155             }
156              
157 232         1005 my $ret = $class->_export_tag($tag, @_);
158              
159 232 50       3669 croak "No such tag: $tag" unless($ret);
160              
161 232 50       885 return wantarray ? @$ret : $ret;
162             }
163              
164             sub add_export_tags
165             {
166 0     0 0 0 my($class) = shift;
167              
168 0         0 while(@_)
169             {
170 0         0 my($tag, $arg) = (shift, shift);
171 0         0 $class->export_tag($tag, $arg);
172             }
173             }
174              
175             sub add_to_export_tag
176             {
177 0     0 0 0 my($class, $tag) = (shift, shift);
178 0         0 my $list = $class->export_tag($tag);
179 0         0 push(@$list, @_);
180             }
181              
182             *delete_export_tag = \&delete_export_tags;
183              
184             sub pre_import_hook
185             {
186 2532     2532 0 4449 my($class, $symbol) = (shift, shift);
187              
188 2532 0 0     5603 if(@_ && (@_ > 1 || (ref $_[0] && (ref $_[0] || '') !~ /\A(?:ARRAY|CODE)\z/)))
      33        
189             {
190 0         0 croak 'pre_import_hook() expects either a single symbol name argument, ',
191             'or a symbol name and a code reference or a reference to an array ',
192             'of code references';
193             }
194              
195 2532 50       4490 if(@_)
196             {
197 0 0       0 unless(ref $_[0] eq 'ARRAY')
198             {
199 0         0 $_[0] = [ $_[0] ];
200             }
201             }
202              
203 2532   50     6148 my $ret = $class->_pre_import_hook($symbol, @_) || [];
204              
205 2532 50       39412 return wantarray ? @$ret : $ret;
206             }
207              
208 2532     2532 0 5223 sub pre_import_hooks { shift->pre_import_hook(shift) }
209              
210             *delete_pre_import_hook = \&delete_pre_import_hooks;
211              
212             1;