line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Devel::GlobalSub;
|
2
|
2
|
|
|
2
|
|
56096
|
use 5.006;
|
|
2
|
|
|
|
|
7
|
|
3
|
2
|
|
|
2
|
|
9
|
use strict;
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
48
|
|
4
|
2
|
|
|
2
|
|
10
|
use warnings;
|
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
377
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.03';
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
unshift @INC, \&_inject;
|
9
|
|
|
|
|
|
|
my $seen;
|
10
|
|
|
|
|
|
|
my @EXPORT;
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub import {
|
13
|
2
|
|
|
2
|
|
11
|
my $self = shift;
|
14
|
2
|
|
|
|
|
7
|
my ($package, $file, $line) = caller;
|
15
|
2
|
|
|
|
|
12
|
for my $name (@_) {
|
16
|
2
|
|
|
|
|
3
|
my $full_name = $name;
|
17
|
2
|
50
|
|
|
|
7
|
unless ($name =~ /::/) {
|
18
|
2
|
|
|
|
|
5
|
$full_name = "${package}::$name";
|
19
|
|
|
|
|
|
|
}
|
20
|
2
|
|
|
|
|
59
|
push @EXPORT, $full_name;
|
21
|
|
|
|
|
|
|
}
|
22
|
|
|
|
|
|
|
}
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub _inject {
|
25
|
2
|
|
|
2
|
|
15
|
no strict 'refs';
|
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
427
|
|
26
|
44
|
|
|
44
|
|
216884
|
my @known_packages = keys %{_get_known_packages()};
|
|
44
|
|
|
|
|
129
|
|
27
|
44
|
|
|
|
|
625
|
my $caller = caller;
|
28
|
44
|
|
|
|
|
4713
|
for my $sub (@EXPORT) {
|
29
|
76
|
|
|
|
|
760
|
my ($sub_pack, $sub_name) = split /::([^:]+)$/, $sub;
|
30
|
76
|
|
|
|
|
6152
|
for my $package (sort @known_packages) {
|
31
|
15452
|
100
|
|
|
|
17895
|
if (not defined &{"${package}::$sub_name"}) {
|
|
15452
|
|
|
|
|
70370
|
|
32
|
460
|
|
|
|
|
686
|
*{"${package}::$sub_name"} = \&{$sub};
|
|
460
|
|
|
|
|
2493
|
|
|
460
|
|
|
|
|
895
|
|
33
|
|
|
|
|
|
|
}
|
34
|
|
|
|
|
|
|
}
|
35
|
|
|
|
|
|
|
}
|
36
|
|
|
|
|
|
|
}
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub _get_known_packages {
|
39
|
264
|
100
|
|
264
|
|
2348
|
my @packs = @_ ? @_ : 'main';
|
40
|
264
|
|
|
|
|
854
|
my $result = {main => 1};
|
41
|
264
|
|
|
|
|
485
|
my @todo;
|
42
|
264
|
|
|
|
|
489
|
for my $pack (@packs) {
|
43
|
2
|
|
|
2
|
|
22
|
no strict 'refs';
|
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
452
|
|
44
|
9072
|
|
|
|
|
12465
|
while (my ($key, $val) = each %{*{"$pack\::"}}) {
|
|
186065
|
|
|
|
|
224946
|
|
|
186065
|
|
|
|
|
675594
|
|
45
|
176993
|
|
|
|
|
267882
|
local(*ENTRY) = $val;
|
46
|
176993
|
100
|
66
|
|
|
625560
|
if (
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
47
|
|
|
|
|
|
|
defined $val &&
|
48
|
|
|
|
|
|
|
defined *ENTRY{HASH} &&
|
49
|
|
|
|
|
|
|
$key =~ /::$/ &&
|
50
|
|
|
|
|
|
|
$key ne 'main::' &&
|
51
|
|
|
|
|
|
|
$key ne '::'
|
52
|
|
|
|
|
|
|
) {
|
53
|
9028
|
100
|
|
|
|
18743
|
my $p = $pack ne 'main' ? "$pack\::" : '';
|
54
|
9028
|
|
|
|
|
26661
|
($p .= $key) =~ s/::$//;
|
55
|
9028
|
|
|
|
|
19503
|
$result->{$p}++;
|
56
|
9028
|
|
|
|
|
21117
|
push @todo, $p;
|
57
|
|
|
|
|
|
|
}
|
58
|
|
|
|
|
|
|
}
|
59
|
|
|
|
|
|
|
}
|
60
|
264
|
100
|
|
|
|
3015
|
$result = {%$result, %{_get_known_packages(@todo)}} if @todo;
|
|
220
|
|
|
|
|
1369
|
|
61
|
264
|
|
|
|
|
11431
|
$result;
|
62
|
|
|
|
|
|
|
}
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
1;
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head1 NAME
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Devel::GlobalSub - Automagically import a subroutine into all namespaces
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=head1 VERSION
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
Version 0.03
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
*** WARNING ***
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
This module will allow you to import one or more subroutines into all namespaces automatically.
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Please note: This is generally A REALLY BAD IDEA. You should never use this module in production environments. If you need your project to import subroutines into some namespaces, do it the normal way: using Exporter or some other controlled method.
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
This module should be useful only for development purposes. For example, when you temporarily want a certain subroutine to be available anywhere in a project for debugging purposes.
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
Using this module for purposes other than development/debugging is a terrible idea. You've been warned.
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
You can use this module
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
To ensure this module to properly work, loading it should be the very first thing your code does. Ideally, you shouldn't even use the module in your code, but in your call to Perl (see bellow). If this module is called late, it might not be able to discover all known namespaces and consequently not be able to import your desired subroutines.
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
First, you want to write a module of your own, where you can define which subroutines will be globally available. Example:
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# File: MyGlobalSubs.pm
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# Very first thing in your code:
|
96
|
|
|
|
|
|
|
use Devel::GlobalSub qw(global_sub_1 global_sub_2);
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub global_sub_1 {
|
99
|
|
|
|
|
|
|
print "I'm global_sub_1 being called!\n";
|
100
|
|
|
|
|
|
|
}
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub global_sub_2 {
|
103
|
|
|
|
|
|
|
print "I'm global_sub_2 being called!\n";
|
104
|
|
|
|
|
|
|
}
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
1;
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
Later, the ideal point in time to inject your global functions, is in the call to Perl. Example:
|
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
joe@devbox:~$ perl -MMyGlobalSubs some_script.pl
|
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
If you need to tell perl where your module is, you can also do this, assuming you have your module at /home/joe/my_perl_libs/MyGlobalSubs.pm:
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
joe@devbox:~$ perl -I/home/joe/my_perl_libs -MMyGlobalSubs some_script.pl
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
If that's is not possible for you for any reason, then you can simply call your module in your script. But, it should be the first thing that gets loaded in your code, so it should be also be called in the main script being executed. Example:
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
#!/usr/bin/perl
|
119
|
|
|
|
|
|
|
# File: some_script.pl
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
use MyGlobalSubs qw(exported_1 exported_2); # <- Very first thing in your code
|
122
|
|
|
|
|
|
|
use strict;
|
123
|
|
|
|
|
|
|
use warnings;
|
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# ... the rest of your code
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head1 EXPORT
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
None.
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head1 SUBROUTINES/METHODS
|
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=head2 Devel::GlobalSub->import(@list_of_sub_names)
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
You shouldn't ever need to call import. This module works only if it is called at compile time. By simply C |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
use Devel::GlobalSub qw(your_global_sub1 your_global_sub_2 your_global_sub_3 etc);
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
It needs to receive the names of the subroutines you want to export everywhere. For exmaple:
|
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# File: MyGlobalSubs.pm
|
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
use Devel::GlobalSub qw(global_sub_1 global_sub_2); # Just the names, not references
|
146
|
|
|
|
|
|
|
use strict;
|
147
|
|
|
|
|
|
|
use warnings;
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# Define the subs you are exporting:
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub global_sub_1 {
|
152
|
|
|
|
|
|
|
print "I'm global_sub_1 being called!\n";
|
153
|
|
|
|
|
|
|
}
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub global_sub_2 {
|
156
|
|
|
|
|
|
|
print "I'm global_sub_2 being called!\n";
|
157
|
|
|
|
|
|
|
}
|
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
1;
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
If you call this module after having called other modules, you might not see your functions exported everywhere, or at all.
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=head1 AUTHOR
|
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
Francisco Zarabozo, C<< >>
|
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=head1 BACKGROUND/WHY
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
As noted at the beginning: This is generally a really bad idea and it shouldn't be ever used as a permanent solution. So, why did I write it?
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
I work on big projects at my everyday job. Many under platforms like Catalyst or Mojolicious. Some times, I need to do some custom debugging in them and I use some personal debugging modules/functions for that. For example, to send deugging information/messages to a custom file I'm following through `tail -f` in a separate console, away from the rest of the system logging, making it really easy to read for me.
|
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
I found myself constantly wanting to use my custom tools, and having to edit each file in the project where I wanted to run them, having to C |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
I wanted something cleaner, quick to type, that didn't need me to add unnecessary, some times dangerous lines to the files. I resolved it with this module. I include it in my call to Perl as:
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
perl -I/home/me/perllibs -MMyDebuggingModule some_project_startup_script.pl -D
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
And with that, I can suddenly put a line in the middle of any file in the project like this:
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# Some code...
|
182
|
|
|
|
|
|
|
my_debug('Hi there, here are some objects:', $request, $stash, $schema);
|
183
|
|
|
|
|
|
|
# Some more code
|
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
After my work is complete, it's a lot easier to search for the lines I need to delete this way. Also, there's no possible way this will run in another machine, as it is not defined anywhere for real.
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=head1 BUGS
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through
|
190
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll
|
191
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes.
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=head1 SUPPORT
|
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command.
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
perldoc Devel::GlobalSub
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
You can also look for information at:
|
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=over 4
|
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here)
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
L
|
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
L
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=item * CPAN Ratings
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
L
|
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=item * Search CPAN
|
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
L
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=back
|
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS
|
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
This software is copyright (c) 2021 by Francisco Zarabozo.
|
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under
|
232
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself.
|
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=cut
|