This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
more pod patches
[perl5.git] / ext / Filter / Util / Call / Call.pm
CommitLineData
2c4bb738
JH
1package Filter::Util::Call ;
2
3require 5.002 ;
4require DynaLoader;
5require Exporter;
6use Carp ;
7use strict;
4176d4e4 8use warnings;
2c4bb738
JH
9use vars qw($VERSION @ISA @EXPORT) ;
10
11@ISA = qw(Exporter DynaLoader);
12@EXPORT = qw( filter_add filter_del filter_read filter_read_exact) ;
4176d4e4 13$VERSION = "1.05" ;
2c4bb738
JH
14
15sub filter_read_exact($)
16{
17 my ($size) = @_ ;
18 my ($left) = $size ;
19 my ($status) ;
20
21 croak ("filter_read_exact: size parameter must be > 0")
22 unless $size > 0 ;
23
24 # try to read a block which is exactly $size bytes long
25 while ($left and ($status = filter_read($left)) > 0) {
26 $left = $size - length $_ ;
27 }
28
29 # EOF with pending data is a special case
30 return 1 if $status == 0 and length $_ ;
31
32 return $status ;
33}
34
35sub filter_add($)
36{
37 my($obj) = @_ ;
38
39 # Did we get a code reference?
40 my $coderef = (ref $obj eq 'CODE') ;
41
42 # If the parameter isn't already a reference, make it one.
43 $obj = \$obj unless ref $obj ;
44
45 $obj = bless ($obj, (caller)[0]) unless $coderef ;
46
47 # finish off the installation of the filter in C.
48 Filter::Util::Call::real_import($obj, (caller)[0], $coderef) ;
49}
50
51bootstrap Filter::Util::Call ;
52
531;
54__END__
55
56=head1 NAME
57
58Filter::Util::Call - Perl Source Filter Utility Module
59
a5de3055 60=head1 SYNOPSIS
bbc7dcd2 61
a5de3055
PM
62 use Filter::Util::Call ;
63
2c4bb738
JH
64=head1 DESCRIPTION
65
66This module provides you with the framework to write I<Source Filters>
67in Perl.
68
69A I<Perl Source Filter> is implemented as a Perl module. The structure
70of the module can take one of two broadly similar formats. To
71distinguish between them, the first will be referred to as I<method
72filter> and the second as I<closure filter>.
73
74Here is a skeleton for the I<method filter>:
75
76 package MyFilter ;
bbc7dcd2 77
2c4bb738
JH
78 use Filter::Util::Call ;
79
80 sub import
81 {
82 my($type, @arguments) = @_ ;
83 filter_add([]) ;
84 }
bbc7dcd2 85
2c4bb738
JH
86 sub filter
87 {
88 my($self) = @_ ;
89 my($status) ;
bbc7dcd2 90
2c4bb738
JH
91 $status = filter_read() ;
92 $status ;
93 }
bbc7dcd2 94
2c4bb738
JH
95 1 ;
96
97and this is the equivalent skeleton for the I<closure filter>:
98
99 package MyFilter ;
bbc7dcd2 100
2c4bb738
JH
101 use Filter::Util::Call ;
102
103 sub import
104 {
105 my($type, @arguments) = @_ ;
bbc7dcd2 106
2c4bb738
JH
107 filter_add(
108 sub
109 {
110 my($status) ;
111 $status = filter_read() ;
112 $status ;
113 } )
114 }
bbc7dcd2 115
2c4bb738
JH
116 1 ;
117
118To make use of either of the two filter modules above, place the line
119below in a Perl source file.
120
121 use MyFilter;
122
123In fact, the skeleton modules shown above are fully functional I<Source
124Filters>, albeit fairly useless ones. All they does is filter the
125source stream without modifying it at all.
126
127As you can see both modules have a broadly similar structure. They both
128make use of the C<Filter::Util::Call> module and both have an C<import>
129method. The difference between them is that the I<method filter>
130requires a I<filter> method, whereas the I<closure filter> gets the
131equivalent of a I<filter> method with the anonymous sub passed to
132I<filter_add>.
133
134To make proper use of the I<closure filter> shown above you need to
135have a good understanding of the concept of a I<closure>. See
136L<perlref> for more details on the mechanics of I<closures>.
137
138=head2 B<use Filter::Util::Call>
139
140The following functions are exported by C<Filter::Util::Call>:
141
142 filter_add()
143 filter_read()
144 filter_read_exact()
145 filter_del()
146
147=head2 B<import()>
148
149The C<import> method is used to create an instance of the filter. It is
150called indirectly by Perl when it encounters the C<use MyFilter> line
151in a source file (See L<perlfunc/import> for more details on
152C<import>).
153
154It will always have at least one parameter automatically passed by Perl
155- this corresponds to the name of the package. In the example above it
156will be C<"MyFilter">.
157
158Apart from the first parameter, import can accept an optional list of
159parameters. These can be used to pass parameters to the filter. For
160example:
161
162 use MyFilter qw(a b c) ;
163
164will result in the C<@_> array having the following values:
165
166 @_ [0] => "MyFilter"
167 @_ [1] => "a"
168 @_ [2] => "b"
169 @_ [3] => "c"
170
171Before terminating, the C<import> function must explicitly install the
172filter by calling C<filter_add>.
173
174B<filter_add()>
175
176The function, C<filter_add>, actually installs the filter. It takes one
177parameter which should be a reference. The kind of reference used will
178dictate which of the two filter types will be used.
179
180If a CODE reference is used then a I<closure filter> will be assumed.
181
182If a CODE reference is not used, a I<method filter> will be assumed.
183In a I<method filter>, the reference can be used to store context
184information. The reference will be I<blessed> into the package by
185C<filter_add>.
186
187See the filters at the end of this documents for examples of using
188context information using both I<method filters> and I<closure
189filters>.
190
191=head2 B<filter() and anonymous sub>
192
193Both the C<filter> method used with a I<method filter> and the
194anonymous sub used with a I<closure filter> is where the main
195processing for the filter is done.
196
197The big difference between the two types of filter is that the I<method
198filter> uses the object passed to the method to store any context data,
199whereas the I<closure filter> uses the lexical variables that are
200maintained by the closure.
201
202Note that the single parameter passed to the I<method filter>,
203C<$self>, is the same reference that was passed to C<filter_add>
204blessed into the filter's package. See the example filters later on for
205details of using C<$self>.
206
207Here is a list of the common features of the anonymous sub and the
208C<filter()> method.
209
210=over 5
211
212=item B<$_>
213
214Although C<$_> doesn't actually appear explicitly in the sample filters
215above, it is implicitly used in a number of places.
216
217Firstly, when either C<filter> or the anonymous sub are called, a local
218copy of C<$_> will automatically be created. It will always contain the
219empty string at this point.
220
221Next, both C<filter_read> and C<filter_read_exact> will append any
222source data that is read to the end of C<$_>.
223
224Finally, when C<filter> or the anonymous sub are finished processing,
225they are expected to return the filtered source using C<$_>.
226
227This implicit use of C<$_> greatly simplifies the filter.
228
229=item B<$status>
230
231The status value that is returned by the user's C<filter> method or
232anonymous sub and the C<filter_read> and C<read_exact> functions take
233the same set of values, namely:
234
235 < 0 Error
236 = 0 EOF
237 > 0 OK
238
239=item B<filter_read> and B<filter_read_exact>
240
241These functions are used by the filter to obtain either a line or block
242from the next filter in the chain or the actual source file if there
243aren't any other filters.
244
245The function C<filter_read> takes two forms:
246
247 $status = filter_read() ;
248 $status = filter_read($size) ;
249
250The first form is used to request a I<line>, the second requests a
251I<block>.
252
253In line mode, C<filter_read> will append the next source line to the
254end of the C<$_> scalar.
255
256In block mode, C<filter_read> will append a block of data which is <=
257C<$size> to the end of the C<$_> scalar. It is important to emphasise
258the that C<filter_read> will not necessarily read a block which is
259I<precisely> C<$size> bytes.
260
261If you need to be able to read a block which has an exact size, you can
262use the function C<filter_read_exact>. It works identically to
263C<filter_read> in block mode, except it will try to read a block which
264is exactly C<$size> bytes in length. The only circumstances when it
265will not return a block which is C<$size> bytes long is on EOF or
266error.
267
268It is I<very> important to check the value of C<$status> after I<every>
269call to C<filter_read> or C<filter_read_exact>.
270
271=item B<filter_del>
272
273The function, C<filter_del>, is used to disable the current filter. It
274does not affect the running of the filter. All it does is tell Perl not
275to call filter any more.
276
277See L<Example 4: Using filter_del> for details.
278
279=back
280
281=head1 EXAMPLES
282
283Here are a few examples which illustrate the key concepts - as such
284most of them are of little practical use.
285
286The C<examples> sub-directory has copies of all these filters
287implemented both as I<method filters> and as I<closure filters>.
288
289=head2 Example 1: A simple filter.
290
291Below is a I<method filter> which is hard-wired to replace all
292occurrences of the string C<"Joe"> to C<"Jim">. Not particularly
293Useful, but it is the first example and I wanted to keep it simple.
294
295 package Joe2Jim ;
bbc7dcd2 296
2c4bb738
JH
297 use Filter::Util::Call ;
298
299 sub import
300 {
301 my($type) = @_ ;
bbc7dcd2 302
2c4bb738
JH
303 filter_add(bless []) ;
304 }
bbc7dcd2 305
2c4bb738
JH
306 sub filter
307 {
308 my($self) = @_ ;
309 my($status) ;
bbc7dcd2 310
2c4bb738
JH
311 s/Joe/Jim/g
312 if ($status = filter_read()) > 0 ;
313 $status ;
314 }
bbc7dcd2 315
2c4bb738
JH
316 1 ;
317
318Here is an example of using the filter:
319
320 use Joe2Jim ;
321 print "Where is Joe?\n" ;
322
323And this is what the script above will print:
324
325 Where is Jim?
326
327=head2 Example 2: Using the context
328
329The previous example was not particularly useful. To make it more
330general purpose we will make use of the context data and allow any
331arbitrary I<from> and I<to> strings to be used. This time we will use a
332I<closure filter>. To reflect its enhanced role, the filter is called
333C<Subst>.
334
335 package Subst ;
bbc7dcd2 336
2c4bb738
JH
337 use Filter::Util::Call ;
338 use Carp ;
bbc7dcd2 339
2c4bb738
JH
340 sub import
341 {
342 croak("usage: use Subst qw(from to)")
343 unless @_ == 3 ;
344 my ($self, $from, $to) = @_ ;
345 filter_add(
346 sub
347 {
348 my ($status) ;
349 s/$from/$to/
350 if ($status = filter_read()) > 0 ;
351 $status ;
352 })
353 }
354 1 ;
355
356and is used like this:
357
358 use Subst qw(Joe Jim) ;
359 print "Where is Joe?\n" ;
360
361
362=head2 Example 3: Using the context within the filter
363
364Here is a filter which a variation of the C<Joe2Jim> filter. As well as
365substituting all occurrences of C<"Joe"> to C<"Jim"> it keeps a count
366of the number of substitutions made in the context object.
367
368Once EOF is detected (C<$status> is zero) the filter will insert an
369extra line into the source stream. When this extra line is executed it
370will print a count of the number of substitutions actually made.
371Note that C<$status> is set to C<1> in this case.
372
373 package Count ;
bbc7dcd2 374
2c4bb738 375 use Filter::Util::Call ;
bbc7dcd2 376
2c4bb738
JH
377 sub filter
378 {
379 my ($self) = @_ ;
380 my ($status) ;
bbc7dcd2 381
2c4bb738
JH
382 if (($status = filter_read()) > 0 ) {
383 s/Joe/Jim/g ;
384 ++ $$self ;
385 }
386 elsif ($$self >= 0) { # EOF
387 $_ = "print q[Made ${$self} substitutions\n]" ;
388 $status = 1 ;
389 $$self = -1 ;
390 }
391
392 $status ;
393 }
bbc7dcd2 394
2c4bb738
JH
395 sub import
396 {
397 my ($self) = @_ ;
398 my ($count) = 0 ;
399 filter_add(\$count) ;
400 }
bbc7dcd2 401
2c4bb738
JH
402 1 ;
403
404Here is a script which uses it:
405
406 use Count ;
407 print "Hello Joe\n" ;
408 print "Where is Joe\n" ;
409
410Outputs:
411
412 Hello Jim
413 Where is Jim
414 Made 2 substitutions
415
416=head2 Example 4: Using filter_del
417
418Another variation on a theme. This time we will modify the C<Subst>
419filter to allow a starting and stopping pattern to be specified as well
420as the I<from> and I<to> patterns. If you know the I<vi> editor, it is
421the equivalent of this command:
422
423 :/start/,/stop/s/from/to/
424
425When used as a filter we want to invoke it like this:
426
427 use NewSubst qw(start stop from to) ;
428
429Here is the module.
430
431 package NewSubst ;
bbc7dcd2 432
2c4bb738
JH
433 use Filter::Util::Call ;
434 use Carp ;
bbc7dcd2 435
2c4bb738
JH
436 sub import
437 {
438 my ($self, $start, $stop, $from, $to) = @_ ;
439 my ($found) = 0 ;
440 croak("usage: use Subst qw(start stop from to)")
441 unless @_ == 5 ;
bbc7dcd2 442
2c4bb738
JH
443 filter_add(
444 sub
445 {
446 my ($status) ;
bbc7dcd2 447
2c4bb738 448 if (($status = filter_read()) > 0) {
bbc7dcd2 449
2c4bb738
JH
450 $found = 1
451 if $found == 0 and /$start/ ;
bbc7dcd2 452
2c4bb738
JH
453 if ($found) {
454 s/$from/$to/ ;
455 filter_del() if /$stop/ ;
456 }
bbc7dcd2 457
2c4bb738
JH
458 }
459 $status ;
460 } )
bbc7dcd2 461
2c4bb738 462 }
bbc7dcd2 463
2c4bb738
JH
464 1 ;
465
466=head1 AUTHOR
467
468Paul Marquess
469
470=head1 DATE
471
47226th January 1996
473
474=cut
475