File Coverage

blib/arch/Panda/Export.pm
Criterion Covered Total %
statement 2 2 100.0
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 3 3 100.0


line stmt bran cond sub pod time code
1             package Panda::Export;
2 2     2   28694 use 5.012;
  2         4  
3              
4             our $VERSION = '2.2.5';
5              
6             =head1 NAME
7              
8             Panda::Export - Replacement for Exporter.pm + const.pm written in C, also provides C API.
9              
10             =cut
11              
12             require Panda::XSLoader;
13             Panda::XSLoader::load();
14              
15             =head1 SYNOPSIS
16              
17             =head2 Exporting functions
18              
19             package MyModule;
20             use parent 'Panda::Export';
21            
22             sub mysub { ... }
23             sub mysub2 { ... }
24            
25             1;
26            
27             package Somewhere;
28             use MyModule qw/mysub mysub2/;
29            
30             mysub();
31            
32             =head2 Creating and using constants (without export)
33              
34             package MyModule;
35            
36             use Panda::Export
37             CONST1 => 1,
38             CONST2 => 'string';
39            
40             say CONST1;
41             say CONST2;
42              
43             =head2 Creating and using constants with export
44              
45             package MyModule;
46             use parent 'Panda::Export';
47            
48             use Panda::Export {
49             CONST1 => 1,
50             CONST2 => 'string',
51             };
52            
53             say CONST1;
54             say CONST2;
55            
56             package Somewhere;
57            
58             use MyModule;
59            
60             say CONST1;
61             say CONST2;
62            
63             =head1 C SYNOPSIS
64              
65             #include
66             using namespace xs::exp;
67            
68             // one-by-one using C types
69             create_constant(stash, "STATUS_OFF", 0);
70             create_constant(stash, "STATUS_ACTIVE", 1);
71             create_constant(stash, "STATUS_SUSPENDED", 2);
72             create_constant(stash, "STATUS_PENDING", 3);
73             create_constant(stash, "DEFAULT_NAME", "john");
74            
75             // one-by-one using SV*
76             create_constant(stash, name_sv, value_sv);
77            
78             // one-by-one using constant_t
79             constant_t constant = {"myconstant", 123};
80             create_constant(stash, constant);
81            
82             // bulk is always faster than one-by-one
83             // bulk using constant_t
84             constant_t constants[] = {
85             {"STATUS_OFF", 0},
86             {"STATUS_ACTIVE", 1},
87             {"STATUS_SUSPENDED", 2},
88             {"STATUS_PENDING", 3},
89             {"DEFAULT_NAME", 0, "john"},
90             {NULL}
91             };
92             create_constants(stash, constants);
93            
94             // bulk using SV* array
95             SV** constant_names_and_values;
96             create_constants(stash, constant_names_and_values);
97            
98             // bulk using hash
99             HV* constants;
100             create_constants(stash, constants);
101            
102             // getting constant names list
103             AV* names = constants_list(stash);
104            
105             // exporting subs
106             const char* name = ...;
107             export_sub(from_stash, to_stash, name);
108             SV* name = ...;
109             export_sub(from_stash, to_stash, name);
110            
111             // bulk
112             const char* names[] = {"sub1", "sub2", "sub3"};
113             export_subs(from, to, sub_names, 3);
114             const char* names[] = {"sub1", "sub2", "sub3", NULL};
115             export_subs(from, to, sub_names);
116             AV* sub_names = ...;
117             export_subs(from, to, sub_names);
118             SV** sub_names = ...;
119             export_subs(from, to, sub_names, items_count);
120            
121             // export all constants
122             export_constants(from, to);
123             // same
124             const char* names[] = {":const"};
125             export_subs(from, to, names, 1);
126              
127             =head1 DESCRIPTION
128              
129             It's very fast not only in runtime but at compile time as well. That means you can create and export/import a
130             lot of constants/functions without slowing down the startup.
131              
132             You can create constants by saying
133              
134             use Panda::Export {CONST_NAME1 => VALUE1, ...};
135             use Panda::Export CONST_NAME1 => VALUE1, ... ;
136              
137             If you want your class to able to export constants or functions you need to derive from Panda::Export.
138              
139             Exports specified constants and functions to caller's package.
140              
141             use MyModule qw/subs list/;
142              
143             Exports nothing
144              
145             use MyModule();
146            
147              
148             Exports all constants only (no functions)
149              
150             use MyModule;
151              
152             Exports functions sub1 and sub2 and all constants
153              
154             use MyModule qw/sub1 sub2 :const/;
155              
156              
157             If Panda::Export discovers name collision while creating or exporting functions or constants it raises an exception.
158             If you specify wrong sub or const name in import list an exception will also be raisen.
159              
160             =head1 C FUNCTIONS
161              
162             Functions marked with C<[pTHX]> must receive C as a first arg.
163              
164             The whole API is thread-safe.
165              
166             struct constant_t {
167             const char* name;
168             int64_t value;
169             const char* svalue;
170             };
171              
172             =head4 void create_constant (HV* stash, SV* name, SV* value) [pTHX]
173              
174             =head4 void create_constant (HV* stash, const char* name, const char* value) [pTHX]
175              
176             =head4 void create_constant (HV* stash, const char* name, int64_t value) [pTHX]
177              
178             Creates constant with name C and value C in package C.
179             Croaks if package already has sub/constant with that name.
180              
181             =head4 void create_constant (HV* stash, constant_t constant) [pTHX]
182              
183             If constant.svalue is null, creates numeric constant (constant.value), otherwise creates string constant (constant.svalue)
184              
185             =head4 void create_constants (HV* stash, HV* constants) [pTHX]
186              
187             Creates a constant for each key/value pair in hash C.
188              
189             =head4 void create_constants (HV* stash, SV** list, size_t items) [pTHX]
190              
191             Creates a constant for each key/value pair in array C.
192             It means that list[0] is a key, list[1] is a value, list[2] is a key, etc...
193             Array should not contain empty slots and empty keys or it will croak.
194             If elements count is odd, last element is ignored. You must pass the size of C in C.
195              
196             =head4 void create_constants (HV* stash, constant_t* list, size_t items = MAX_ITEMS) [pTHX]
197              
198             Creates a constant for each key/value pair in array C.
199             Stops processing list if discovered an element with element.name == NULL. Therefore you must either pass a valid C, or
200             end your list with "{NULL}" value.
201              
202             =head4 void export_sub (HV* from, HV* to, SV* name) [pTHX]
203              
204             =head4 void export_sub (HV* from, HV* to, const char* name) [pTHX]
205              
206             Exports sub/constant with name C from package C to package .
207              
208             =head4 void export_constants (HV* from, HV* to) [pTHX]
209              
210             Exports all constants from package C to package .
211              
212             =head4 void export_subs (HV* from, HV* to, AV* list) [pTHX]
213              
214             Exports contants/subs with names in C.
215              
216             =head4 void export_subs (HV* from, HV* to, SV** list, size_t items) [pTHX]
217              
218             Exports contants/subs with names in C. You must pass the size of C in C.
219              
220             =head4 void export_subs (HV* from, HV* to, const char** list, size_t items = MAX_ITEMS) [pTHX]
221              
222             Exports contants/subs with names in C. Stops processing list if discovered NULL value in list.
223             Therefore you must either pass a valid C, or end your list with NULL value.
224              
225             =head4 AV* constants_list (HV* stash) [pTHX]
226              
227             Returns the list of all constants defined in package C as a perl array.
228              
229             =head3 TIP
230              
231             If you receive SV* as constant/sub name from user, don't get it's content as const char* to call functions which receive const char*.
232             The reason is that those SVs are often so-called "shared hash string", i.e. besides a string itself, they contain its precomputed
233             hash value inside. This may significantly increase perfomance as exporting/creating sub/constants is always a matter of hash lookups.
234              
235             However, if you only have const char*, don't make SV from it, as it will definitly decrease perfomance.
236              
237             =head1 PERFOMANCE
238              
239             Panda::Export is up to 10x faster than const.pm and Exporter.pm at compile-time.
240             The runtime perfomance is the same as it doesn't depend on this module.
241              
242             =head1 AUTHOR
243              
244             Pronin Oleg , Crazy Panda, CP Decision LTD
245              
246             =head1 LICENSE
247              
248             You may distribute this code under the same terms as Perl itself.
249              
250             =cut
251              
252             1;