Version 0.006008
[p5sagit/Devel-Declare.git] / lib / Devel / Declare.pm
CommitLineData
94caac6e 1package Devel::Declare;
2
3use strict;
4use warnings;
5use 5.008001;
6
4eeccf39 7our $VERSION = '0.006008';
0ba8c7aa 8
9use constant DECLARE_NAME => 1;
10use constant DECLARE_PROTO => 2;
53e3ab32 11use constant DECLARE_NONE => 4;
15d0d014 12use constant DECLARE_PACKAGE => 8+1; # name implicit
0ba8c7aa 13
86c3de80 14use vars qw(%declarators %declarator_handlers @ISA);
94caac6e 15use base qw(DynaLoader);
323ae557 16use Scalar::Util 'set_prototype';
39801454 17use B::Hooks::OP::Check 0.19;
94caac6e 18
19bootstrap Devel::Declare;
20
86c3de80 21@ISA = ();
22
8ec78a85 23initialize();
24
94caac6e 25sub import {
0ba8c7aa 26 my ($class, %args) = @_;
94caac6e 27 my $target = caller;
0ba8c7aa 28 if (@_ == 1) { # "use Devel::Declare;"
29 no strict 'refs';
15d0d014 30 foreach my $name (qw(NAME PROTO NONE PACKAGE)) {
53e3ab32 31 *{"${target}::DECLARE_${name}"} = *{"DECLARE_${name}"};
0ba8c7aa 32 }
33 } else {
34 $class->setup_for($target => \%args);
35 }
94caac6e 36}
37
38sub unimport {
39 my ($class) = @_;
40 my $target = caller;
41 $class->teardown_for($target);
42}
43
44sub setup_for {
45 my ($class, $target, $args) = @_;
46 setup();
0ba8c7aa 47 foreach my $key (keys %$args) {
48 my $info = $args->{$key};
49 my ($flags, $sub);
50 if (ref($info) eq 'ARRAY') {
51 ($flags, $sub) = @$info;
52 } elsif (ref($info) eq 'CODE') {
53 $flags = DECLARE_NAME;
54 $sub = $info;
840ebcbb 55 } elsif (ref($info) eq 'HASH') {
56 $flags = 1;
57 $sub = $info;
0ba8c7aa 58 } else {
840ebcbb 59 die "Info for sub ${key} must be [ \$flags, \$sub ] or \$sub or handler hashref";
0ba8c7aa 60 }
61 $declarators{$target}{$key} = $flags;
62 $declarator_handlers{$target}{$key} = $sub;
63 }
94caac6e 64}
65
66sub teardown_for {
67 my ($class, $target) = @_;
68 delete $declarators{$target};
0ba8c7aa 69 delete $declarator_handlers{$target};
94caac6e 70}
71
94caac6e 72my $temp_name;
0ba8c7aa 73my $temp_save;
94caac6e 74
75sub init_declare {
0f070758 76 my ($usepack, $use, $inpack, $name, $proto, $traits) = @_;
53e3ab32 77 my ($name_h, $XX_h, $extra_code)
9026391e 78 = $declarator_handlers{$usepack}{$use}->(
0f070758 79 $usepack, $use, $inpack, $name, $proto, defined(wantarray), $traits
53e3ab32 80 );
15d0d014 81 ($temp_name, $temp_save) = ([], []);
0ba8c7aa 82 if ($name) {
9026391e 83 $name = "${inpack}::${name}" unless $name =~ /::/;
840ebcbb 84 shadow_sub($name, $name_h);
0ba8c7aa 85 }
86 if ($XX_h) {
840ebcbb 87 shadow_sub("${inpack}::X", $XX_h);
0ba8c7aa 88 }
53e3ab32 89 if (defined wantarray) {
90 return $extra_code || '0;';
91 } else {
92 return;
93 }
94caac6e 94}
95
840ebcbb 96sub shadow_sub {
97 my ($name, $cr) = @_;
98 push(@$temp_name, $name);
99 no strict 'refs';
100 my ($pack, $pname) = ($name =~ m/(.+)::([^:]+)/);
101 push(@$temp_save, $pack->can($pname));
840ebcbb 102 no warnings 'redefine';
103 no warnings 'prototype';
104 *{$name} = $cr;
105 set_in_declare(~~@{$temp_name||[]});
106}
107
94caac6e 108sub done_declare {
109 no strict 'refs';
86c3de80 110 my $name = shift(@{$temp_name||[]});
0ba8c7aa 111 die "done_declare called with no temp_name stack" unless defined($name);
86c3de80 112 my $saved = shift(@$temp_save);
15d0d014 113 $name =~ s/(.*):://;
114 my $temp_pack = $1;
0ba8c7aa 115 delete ${"${temp_pack}::"}{$name};
116 if ($saved) {
117 no warnings 'prototype';
118 *{"${temp_pack}::${name}"} = $saved;
119 }
840ebcbb 120 set_in_declare(~~@{$temp_name||[]});
94caac6e 121}
122
323ae557 123sub build_sub_installer {
124 my ($class, $pack, $name, $proto) = @_;
125 return eval "
126 package ${pack};
127 my \$body;
128 sub ${name} (${proto}) :lvalue {\n"
003ac394 129 .' if (wantarray) {
c5912dc7 130 goto &$body;
003ac394 131 }
132 my $ret = $body->(@_);
86c3de80 133 return $ret;
323ae557 134 };
135 sub { ($body) = @_; };';
136}
137
138sub setup_declarators {
139 my ($class, $pack, $to_setup) = @_;
86c3de80 140 die "${class}->setup_declarators(\$pack, \\\%to_setup)"
141 unless defined($pack) && ref($to_setup) eq 'HASH';
142 my %setup_for_args;
323ae557 143 foreach my $name (keys %$to_setup) {
144 my $info = $to_setup->{$name};
145 my $flags = $info->{flags} || DECLARE_NAME;
146 my $run = $info->{run};
147 my $compile = $info->{compile};
148 my $proto = $info->{proto} || '&';
149 my $sub_proto = $proto;
150 # make all args optional to enable lvalue for DECLARE_NONE
151 $sub_proto =~ s/;//; $sub_proto = ';'.$sub_proto;
86c3de80 152 #my $installer = $class->build_sub_installer($pack, $name, $proto);
153 my $installer = $class->build_sub_installer($pack, $name, '@');
86c3de80 154 $installer->(sub :lvalue {
003ac394 155#{ no warnings 'uninitialized'; warn 'INST: '.join(', ', @_)."\n"; }
c5534496 156 if (@_) {
157 if (ref $_[0] eq 'HASH') {
158 shift;
003ac394 159 if (wantarray) {
160 my @ret = $run->(undef, undef, @_);
161 return @ret;
162 }
c5534496 163 my $r = $run->(undef, undef, @_);
164 return $r;
165 } else {
003ac394 166 return @_[1..$#_];
c5534496 167 }
86c3de80 168 }
169 return my $sv;
170 });
171 $setup_for_args{$name} = [
172 $flags,
173 sub {
0f070758 174 my ($usepack, $use, $inpack, $name, $proto, $shift_hashref, $traits) = @_;
175 my $extra_code = $compile->($name, $proto, $traits);
003ac394 176 my $main_handler = sub { shift if $shift_hashref;
c5534496 177 ("DONE", $run->($name, $proto, @_));
003ac394 178 };
86c3de80 179 my ($name_h, $XX);
180 if (defined $proto) {
181 $name_h = sub :lvalue { return my $sv; };
182 $XX = $main_handler;
c5534496 183 } elsif (defined $name && length $name) {
86c3de80 184 $name_h = $main_handler;
185 }
003ac394 186 $extra_code ||= '';
187 $extra_code = '}, sub {'.$extra_code;
86c3de80 188 return ($name_h, $XX, $extra_code);
189 }
190 ];
323ae557 191 }
86c3de80 192 $class->setup_for($pack, \%setup_for_args);
193}
194
195sub install_declarator {
196 my ($class, $target_pack, $target_name, $flags, $filter, $handler) = @_;
197 $class->setup_declarators($target_pack, {
198 $target_name => {
199 flags => $flags,
200 compile => $filter,
201 run => $handler,
202 }
203 });
323ae557 204}
205
04a8a223 206sub linestr_callback_rv2cv {
207 my ($name, $offset) = @_;
208 $offset += toke_move_past_token($offset);
209 my $pack = get_curstash_name();
210 my $flags = $declarators{$pack}{$name};
211 my ($found_name, $found_proto);
04a8a223 212 if ($flags & DECLARE_NAME) {
213 $offset += toke_skipspace($offset);
214 my $linestr = get_linestr();
215 if (substr($linestr, $offset, 2) eq '::') {
216 substr($linestr, $offset, 2) = '';
217 set_linestr($linestr);
218 }
219 if (my $len = toke_scan_word($offset, $flags & DECLARE_PACKAGE)) {
220 $found_name = substr($linestr, $offset, $len);
221 $offset += $len;
04a8a223 222 }
223 }
224 if ($flags & DECLARE_PROTO) {
225 $offset += toke_skipspace($offset);
226 my $linestr = get_linestr();
227 if (substr($linestr, $offset, 1) eq '(') {
228 my $length = toke_scan_str($offset);
229 $found_proto = get_lex_stuff();
230 clear_lex_stuff();
231 my $replace =
232 ($found_name ? ' ' : '=')
233 .'X'.(' ' x length($found_proto));
234 $linestr = get_linestr();
235 substr($linestr, $offset, $length) = $replace;
236 set_linestr($linestr);
237 $offset += $length;
04a8a223 238 }
239 }
240 my @args = ($pack, $name, $pack, $found_name, $found_proto);
04a8a223 241 $offset += toke_skipspace($offset);
242 my $linestr = get_linestr();
243 if (substr($linestr, $offset, 1) eq '{') {
244 my $ret = init_declare(@args);
245 $offset++;
246 if (defined $ret && length $ret) {
247 substr($linestr, $offset, 0) = $ret;
248 set_linestr($linestr);
249 }
250 } else {
251 init_declare(@args);
252 }
253 #warn "linestr now ${linestr}";
254}
255
569ac469 256sub linestr_callback_const {
04a8a223 257 my ($name, $offset) = @_;
258 my $pack = get_curstash_name();
259 my $flags = $declarators{$pack}{$name};
260 if ($flags & DECLARE_NAME) {
261 $offset += toke_move_past_token($offset);
262 $offset += toke_skipspace($offset);
263 if (toke_scan_word($offset, $flags & DECLARE_PACKAGE)) {
264 my $linestr = get_linestr();
265 substr($linestr, $offset, 0) = '::';
266 set_linestr($linestr);
267 }
268 }
569ac469 269}
270
271sub linestr_callback {
272 my $type = shift;
840ebcbb 273 my $name = $_[0];
274 my $pack = get_curstash_name();
275 my $handlers = $declarator_handlers{$pack}{$name};
276 if (ref $handlers eq 'CODE') {
277 my $meth = "linestr_callback_${type}";
278 __PACKAGE__->can($meth)->(@_);
279 } elsif (ref $handlers eq 'HASH') {
280 if ($handlers->{$type}) {
281 $handlers->{$type}->(@_);
282 }
283 } else {
284 die "PANIC: unknown thing in handlers for $pack $name: $handlers";
285 }
569ac469 286}
287
94caac6e 288=head1 NAME
289
7e31b6e3 290Devel::Declare - Adding keywords to perl, in perl
94caac6e 291
292=head1 SYNOPSIS
293
1795217c 294 use Method::Signatures;
295 # or ...
296 use MooseX::Declare;
297 # etc.
298
299 # Use some new and exciting syntax like:
300 method hello (Str :$who, Int :$age where { $_ > 0 }) {
301 $self->say("Hello ${who}, I am ${age} years old!");
302 }
303
304=head1 DESCRIPTION
305
306L<Devel::Declare> can install subroutines called declarators which locally take
307over Perl's parser, allowing the creation of new syntax.
308
309This document describes how to create a simple declarator.
310
311=head1 USAGE
312
313We'll demonstrate the usage of C<Devel::Declare> with a motivating example: a new
314C<method> keyword, which acts like the builtin C<sub>, but automatically unpacks
315C<$self> and the other arguments.
316
317 package My::Methods;
318 use Devel::Declare;
319
320=head2 Creating a declarator with C<setup_for>
321
322You will typically create
323
324 sub import {
325 my $class = shift;
326 my $caller = caller;
327
328 Devel::Declare->setup_for(
329 $caller,
330 { method => { const => \&parser } }
331 );
332 no strict 'refs';
333 *{$caller.'::method'} = sub (&) {};
334 }
335
336Starting from the end of this import routine, you'll see that we're creating a
337subroutine called C<method> in the caller's namespace. Yes, that's just a normal
338subroutine, and it does nothing at all (yet!) Note the prototype C<(&)> which means
339that the caller would call it like so:
340
341 method {
342 my ($self, $arg1, $arg2) = @_;
343 ...
344 }
345
346However we want to be able to call it like this
347
348 method foo ($arg1, $arg2) {
349 ...
350 }
351
352That's why we call C<setup_for> above, to register the declarator 'method' with a custom
353parser, as per the next section. It acts on an optype, usually C<'const'> as above.
354(Other valid values are C<'check'> and C<'rv2cv'>).
355
356For a simpler way to install new methods, see also L<Devel::Declare::MethodInstaller::Simple>
357
358=head2 Writing a parser subroutine
359
360This subroutine is called at I<compilation> time, and allows you to read the custom
361syntaxes that we want (in a syntax that may or may not be valid core Perl 5) and
362munge it so that the result will be parsed by the C<perl> compiler.
363
364For this example, we're defining some globals for convenience:
365
2ee34f20 366 our ($Declarator, $Offset);
1795217c 367
368Then we define a parser subroutine to handle our declarator. We'll look at this in
369a few chunks.
370
371 sub parser {
372 local ($Declarator, $Offset) = @_;
373
374C<Devel::Declare> provides some very low level utility methods to parse character
375strings. We'll define some useful higher level routines below for convenience,
376and we can use these to parse the various elements in our new syntax.
377
378Notice how our parser subroutine is invoked at compile time,
379when the C<perl> parser is pointed just I<before> the declarator name.
380
381 skip_declarator; # step past 'method'
382 my $name = strip_name; # strip out the name 'foo', if present
383 my $proto = strip_proto; # strip out the prototype '($arg1, $arg2)', if present
384
385Now we can prepare some code to 'inject' into the new subroutine. For example we
386might want the method as above to have C<my ($self, $arg1, $arg2) = @_> injected at
387the beginning of it. We also do some clever stuff with scopes that we'll look
388at shortly.
389
390 my $inject = make_proto_unwrap($proto);
391 if (defined $name) {
392 $inject = scope_injector_call().$inject;
393 }
394 inject_if_block($inject);
395
396We've now managed to change C<method ($arg1, $arg2) { ... }> into C<method {
397injected_code; ... }>. This will compile... but we've lost the name of the
398method!
399
400In a cute (or horrifying, depending on your perspective) trick, we temporarily
401change the definition of the subroutine C<method> itself, to specialise it with
402the C<$name> we stripped, so that it assigns the code block to that name.
403
404Even though the I<next> time C<method> is compiled, it will be
405redefined again, C<perl> caches these definitions in its parse
406tree, so we'll always get the right one!
407
408Note that we also handle the case where there was no name, allowing
409an anonymous method analogous to an anonymous subroutine.
410
411 if (defined $name) {
412 $name = join('::', Devel::Declare::get_curstash_name(), $name)
413 unless ($name =~ /::/);
414 shadow(sub (&) { no strict 'refs'; *{$name} = shift; });
415 } else {
416 shadow(sub (&) { shift });
417 }
418 }
419
420
421=head2 Parser utilities in detail
422
423For simplicity, we're using global variables like C<$Offset> in these examples.
424You may prefer to look at L<Devel::Declare::Context::Simple>, which
425encapsulates the context much more cleanly.
426
427=head3 C<skip_declarator>
428
429This simple parser just moves across a 'token'. The common case is
430to skip the declarator, i.e. to move to the end of the string
431'method' and before the prototype and code block.
432
2ee34f20 433 sub skip_declarator {
434 $Offset += Devel::Declare::toke_move_past_token($Offset);
435 }
1795217c 436
437=head4 C<toke_move_past_token>
438
439This builtin parser simply moves past a 'token' (matching C</[a-zA-Z_]\w*/>)
440It takes an offset into the source document, and skips past the token.
441It returns the number of characters skipped.
442
443=head3 C<strip_name>
444
445This parser skips any whitespace, then scans the next word (again matching a
446'token'). We can then analyse the current line, and manipulate it (using pure
447Perl). In this case we take the name of the method out, and return it.
448
2ee34f20 449 sub strip_name {
450 skipspace;
451 if (my $len = Devel::Declare::toke_scan_word($Offset, 1)) {
452 my $linestr = Devel::Declare::get_linestr();
453 my $name = substr($linestr, $Offset, $len);
454 substr($linestr, $Offset, $len) = '';
455 Devel::Declare::set_linestr($linestr);
456 return $name;
457 }
458 return;
459 }
1795217c 460
461=head4 C<toke_scan_word>
462
463This builtin parser, given an offset into the source document,
464matches a 'token' as above but does not skip. It returns the
465length of the token matched, if any.
466
467=head4 C<get_linestr>
468
469This builtin returns the full text of the current line of the source document.
470
471=head4 C<set_linestr>
472
473This builtin sets the full text of the current line of the source document.
474
475=head3 C<skipspace>
476
477This parser skips whitsepace.
478
479 sub skipspace {
480 $Offset += Devel::Declare::toke_skipspace($Offset);
481 }
482
483=head4 C<toke_skipspace>
484
485This builtin parser, given an offset into the source document,
486skips over any whitespace, and returns the number of characters
487skipped.
488
489=head3 C<strip_proto>
490
491This is a more complex parser that checks if it's found something that
492starts with C<'('> and returns everything till the matching C<')'>.
493
2ee34f20 494 sub strip_proto {
495 skipspace;
1795217c 496
2ee34f20 497 my $linestr = Devel::Declare::get_linestr();
498 if (substr($linestr, $Offset, 1) eq '(') {
499 my $length = Devel::Declare::toke_scan_str($Offset);
500 my $proto = Devel::Declare::get_lex_stuff();
501 Devel::Declare::clear_lex_stuff();
502 $linestr = Devel::Declare::get_linestr();
503 substr($linestr, $Offset, $length) = '';
504 Devel::Declare::set_linestr($linestr);
505 return $proto;
506 }
507 return;
508 }
1795217c 509
510=head4 C<toke_scan_str>
511
512This builtin parser uses Perl's own parsing routines to match a "stringlike"
513expression. Handily, this includes bracketed expressions (just think about
514things like C<q(this is a quote)>).
515
516Also it Does The Right Thing with nested delimiters (like C<q(this (is (a) quote))>).
517
78bb475d 518It returns the effective length of the expression matched. Really, what
519it returns is the difference in position between where the string started,
520within the buffer, and where it finished. If the string extended across
521multiple lines then the contents of the buffer may have been completely
522replaced by the new lines, so this position difference is not the same
523thing as the actual length of the expression matched. However, because
524moving backward in the buffer causes problems, the function arranges
525for the effective length to always be positive, padding the start of
526the buffer if necessary.
527
528Use C<get_lex_stuff> to get the actual matched text, the content of
529the string. Because of the behaviour around multiline strings, you
530can't reliably get this from the buffer. In fact, after the function
531returns, you can't rely on any content of the buffer preceding the end
532of the string.
1795217c 533
8449c31f 534If the string being scanned is not well formed (has no closing delimiter),
535C<toke_scan_str> returns C<undef>. In this case you cannot rely on the
536contents of the buffer.
537
1795217c 538=head4 C<get_lex_stuff>
539
540This builtin returns what was matched by C<toke_scan_str>. To avoid segfaults,
541you should call C<clear_lex_stuff> immediately afterwards.
542
543=head2 Munging the subroutine
544
545Let's look at what we need to do in detail.
546
547=head3 C<make_proto_unwrap>
548
549We may have defined our method in different ways, which will result
550in a different value for our prototype, as parsed above. For example:
551
552 method foo { # undefined
553 method foo () { # ''
554 method foo ($arg1) { # '$arg1'
555
556We deal with them as follows, and return the appropriate C<my ($self, ...) = @_;>
557string.
558
2ee34f20 559 sub make_proto_unwrap {
560 my ($proto) = @_;
561 my $inject = 'my ($self';
562 if (defined $proto) {
563 $inject .= ", $proto" if length($proto);
564 $inject .= ') = @_; ';
565 } else {
566 $inject .= ') = shift;';
567 }
568 return $inject;
569 }
1795217c 570
571=head3 C<inject_if_block>
572
573Now we need to inject it after the opening C<'{'> of the method body.
574We can do this with the building blocks we defined above like C<skipspace>
575and C<get_linestr>.
576
2ee34f20 577 sub inject_if_block {
578 my $inject = shift;
579 skipspace;
580 my $linestr = Devel::Declare::get_linestr;
581 if (substr($linestr, $Offset, 1) eq '{') {
582 substr($linestr, $Offset+1, 0) = $inject;
583 Devel::Declare::set_linestr($linestr);
584 }
585 }
94caac6e 586
1795217c 587=head3 C<scope_injector_call>
588
589We want to be able to handle both named and anonymous methods. i.e.
590
591 method foo () { ... }
592 my $meth = method () { ... };
593
594These will then get rewritten as
595
596 method { ... }
597 my $meth = method { ... };
598
599where 'method' is a subroutine that takes a code block. Spot the problem?
600The first one doesn't have a semicolon at the end of it! Unlike 'sub' which
601is a builtin, this is just a normal statement, so we need to terminate it.
6c1cecd4 602Luckily, using C<B::Hooks::EndOfScope>, we can do this!
1795217c 603
6c1cecd4 604 use B::Hooks::EndOfScope;
1795217c 605
606We'll add this to what gets 'injected' at the beginning of the method source.
607
608 sub scope_injector_call {
609 return ' BEGIN { MethodHandlers::inject_scope }; ';
2ee34f20 610 }
1795217c 611
5bcdf810 612So at the beginning of every method, we are passing a callback that will get invoked
1795217c 613at the I<end> of the method's compilation... i.e. exactly then the closing C<'}'>
614is compiled.
615
616 sub inject_scope {
6c1cecd4 617 on_scope_end {
1795217c 618 my $linestr = Devel::Declare::get_linestr;
619 my $offset = Devel::Declare::get_linestr_offset;
620 substr($linestr, $offset, 0) = ';';
621 Devel::Declare::set_linestr($linestr);
6c1cecd4 622 };
2ee34f20 623 }
94caac6e 624
1795217c 625=head2 Shadowing each method.
626
627=head3 C<shadow>
94caac6e 628
1795217c 629We override the current definition of 'method' using C<shadow>.
94caac6e 630
1795217c 631 sub shadow {
632 my $pack = Devel::Declare::get_curstash_name;
633 Devel::Declare::shadow_sub("${pack}::${Declarator}", $_[0]);
2ee34f20 634 }
94caac6e 635
1795217c 636For a named method we invoked like this:
637
638 shadow(sub (&) { no strict 'refs'; *{$name} = shift; });
639
640So in the case of a C<method foo { ... }>, this call would redefine C<method>
641to be a subroutine that exports 'sub foo' as the (munged) contents of C<{...}>.
642
643The case of an anonymous method is also cute:
644
645 shadow(sub (&) { shift });
646
647This means that
648
649 my $meth = method () { ... };
650
651is rewritten with C<method> taking the codeblock, and returning it as is to become
652the value of C<$meth>.
653
654=head4 C<get_curstash_name>
655
656This returns the package name I<currently being compiled>.
657
658=head4 C<shadow_sub>
659
660Handles the details of redefining the subroutine.
661
662=head1 SEE ALSO
663
664One of the best ways to learn C<Devel::Declare> is still to look at
665modules that use it:
666
667L<http://cpants.perl.org/dist/used_by/Devel-Declare>.
94caac6e 668
dcf29eb6 669=head1 AUTHORS
94caac6e 670
502ba90e 671Matt S Trout - E<lt>mst@shadowcat.co.ukE<gt> - original author
94caac6e 672
02f5a508 673Company: http://www.shadowcat.co.uk/
94caac6e 674Blog: http://chainsawblues.vox.com/
675
1795217c 676Florian Ragwitz E<lt>rafl@debian.orgE<gt> - maintainer
677
0df492b9 678osfameron E<lt>osfameron@cpan.orgE<gt> - first draft of documentation
dcf29eb6 679
107322d1 680=head1 COPYRIGHT AND LICENSE
681
09addf7a 682This library is free software under the same terms as perl itself
683
107322d1 684Copyright (c) 2007, 2008, 2009 Matt S Trout
685
686Copyright (c) 2008, 2009 Florian Ragwitz
94caac6e 687
09addf7a 688stolen_chunk_of_toke.c based on toke.c from the perl core, which is
689
690Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
6912000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
94caac6e 692
693=cut
694
6951;