File Coverage

blib/lib/meta.pm
Criterion Covered Total %
statement 5 5 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 7 7 100.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2023 -- leonerd@leonerd.org.uk
5              
6             package meta;
7              
8 8     8   1650869 use v5.14;
  8         72  
9 8     8   48 use warnings;
  8         22  
  8         1334  
10              
11             # We must do this hackery because `package NAME VER` does not work with _ in VER
12             # https://github.com/Perl/perl5/issues/21499
13             our $VERSION = '0.001_001';
14              
15             require XSLoader;
16             XSLoader::load( __PACKAGE__, $VERSION );
17              
18             # Squash out the _ but only after loading XS
19             $VERSION =~ s/_//g;
20              
21             =head1 NAME
22              
23             C - meta-programming API
24              
25             =head1 SYNOPSIS
26              
27             use v5.14;
28             use meta;
29              
30             my $metapkg = meta::get_package( "MyApp::Some::Package" );
31              
32             $metapkg->add_symbol(
33             '&a_function' => sub { say "New function was created" }
34             );
35              
36             MyApp::Some::Package::a_function();
37              
38             =head1 DESCRIPTION
39              
40             This package provides an API for metaprogramming; that is, allowing code to
41             inspect or manipulate parts of its own program structure. Parts of the perl
42             interpreter itself can be accessed by means of "meta"-objects provided by this
43             package. Methods on these objects allow inspection of details, as well as
44             creating new items or removing existing ones.
45              
46             The intention of this API is to provide a nicer replacement for existing
47             tricks such as C and using globrefs, and also to be a more
48             consistent place to add new abilities, such as more APIs for inspection and
49             alteration of internal structures, metaprogramming around the new C<'class'>
50             feature, and other such uses.
51              
52             =cut
53              
54             =head1 FUNCTIONS
55              
56             =head2 get_package
57              
58             $metapkg = meta::get_package( $pkgname );
59              
60             Returns a metapackage reference representing the given package name, creating
61             it if it did not previously exist.
62              
63             =cut
64              
65             =head1 METHODS ON METAPACKAGES
66              
67             =head2 name
68              
69             $name = $metapkg->name;
70              
71             Returns the name of the package being represented.
72              
73             =head2 get_glob
74              
75             $metaglob = $metapkg->get_glob( $name );
76              
77             Returns a metaglob reference representing the given symbol name within the
78             package, if it exists. Throws an exception if not.
79              
80             =head2 can_glob
81              
82             $metaglob = $metapkg->can_glob( $name );
83              
84             Similar to L but returns undef if the glob does not exist.
85              
86             =head2 get_symbol
87              
88             $metasym = $metapkg->get_symbol( $name );
89              
90             Returns a metasymbol reference representing the given symbol name within the
91             package. The symbol name should include the leading sigil; one of the
92             characters C<*>, C<$>, C<@>, C<%> or C<&>. Throws an exception if the symbol
93             does not exist.
94              
95             =head2 can_symbol
96              
97             $metasym = $metapkg->can_symbol( $name );
98              
99             Similar to L but returns undef if the symbol does ont exist.
100              
101             =head2 add_symbol
102              
103             $metasym = $metapkg->add_symbol( $name, $valueref );
104              
105             Creates a new symbol of the given name in the given package. The new symbol
106             will refer to the item given by reference, whose type must match the sigil
107             of the symbol name. Returns a metasymbol reference as per L. If
108             a symbol already existed of the given name then an exception is thrown.
109              
110             To only conditionally add a symbol if it doesn't already exist, test for it
111             first by using L:
112              
113             $metapkg->can_symbol( '$variable' ) or
114             $metapkg->add_symbol( '$variable', \my $tmp );
115              
116             I that this does not create a copy of a variable, but stores an alias
117             to the referred item itself within the symbol table.
118              
119             $metapkg->add_symbol( '@things', \my @array );
120              
121             push @array, "more", "values";
122             # these values are now visible in the @things array
123              
124             =head2 remove_symbol
125              
126             $metapkg->remove_symbol( $name );
127              
128             Removes a symbol of the given name from the given package. If the symbol was
129             the last item in the glob then the glob too is removed from the package. If
130             the named symbol did not previously exist then an exception is thrown.
131              
132             To only conditionally remove a symbol if it already exists, test for it first
133             by using L:
134              
135             $metapkg->can_symbol( '$variable' ) and
136             $metapkg->remove_symbol( '$variable' );
137              
138             =cut
139              
140             =head1 METHODS ON METASYMBOLS
141              
142             =head2 is_glob, is_scalar, ...
143              
144             $bool = $metasym->is_glob;
145             $bool = $metasym->is_scalar;
146             $bool = $metasym->is_array;
147             $bool = $metasym->is_hash;
148             $bool = $metasym->is_subroutine;
149              
150             Returns true if the symbol being referred to is of the given type, or false if
151             not.
152              
153             =head2 reference
154              
155             $ref = $metasym->reference;
156              
157             Returns a regular Perl reference to the symbol being represented.
158              
159             =cut
160              
161             =head1 METHODS ON METAGLOBS
162              
163             =cut
164              
165             @meta::glob::ISA = qw( meta::symbol );
166              
167             =head2 name
168              
169             $name = $metaglob->basename;
170              
171             Returns the name of the glob I.
172              
173             =head2 get_scalar, get_array, ...
174              
175             $metasym = $metaglob->get_scalar;
176             $metasym = $metaglob->get_array;
177             $metasym = $metaglob->get_hash;
178             $metasym = $metaglob->get_code;
179              
180             Returns a metasymbol reference representing the symbol in the given slot of
181             the glob, if it exists. Throws an exception if not.
182              
183             =head2 can_scalar, can_array, ...
184              
185             Similar to L, L, etc... but returns undef if the
186             given slot does not exist.
187              
188             =cut
189              
190             =head1 METHODS ON METAVARIABLES
191              
192             =cut
193              
194             @meta::variable::ISA = qw( meta::symbol );
195              
196             =head2 value
197              
198             $scalar = $metavar->value;
199             @array = $metavar->value;
200             %hash = $metavar->value;
201              
202             $count = scalar $metavar->value;
203              
204             Returns the current value of the variable, as if it appeared in regular Perl
205             code.
206              
207             =cut
208              
209             =head1 METHODS ON METASUBROUTINES
210              
211             =cut
212              
213             @meta::subroutine::ISA = qw( meta::symbol );
214              
215             =head2 subname
216              
217             $name = $metasub->subname;
218              
219             Returns the (fully-qualified) name of the subroutine.
220              
221             =head2 prototype
222              
223             $proto = $metasub->prototype;
224              
225             Returns the prototype of the subroutine.
226              
227             =cut
228              
229             =head1 AUTHOR
230              
231             Paul Evans
232              
233             =cut
234              
235             0x55AA;