• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /macosx-10.10/CPANInternal-159.1/DateTime-Format-Builder-0.81/lib/DateTime/Format/Builder/Parser/
1package DateTime::Format::Builder::Parser::generic;
2{
3  $DateTime::Format::Builder::Parser::generic::VERSION = '0.81';
4}
5use strict;
6use warnings;
7use Carp;
8use Params::Validate qw(
9    validate SCALAR CODEREF UNDEF
10);
11
12
13
14sub new {
15    my $class = shift;
16    bless {@_}, $class;
17}
18
19
20sub generic_parser {
21    my $class = shift;
22    my %args  = validate(
23        @_,
24        {
25            (
26                map { $_ => { type => CODEREF, optional => 1 } }
27                    qw(
28                    on_match on_fail preprocess postprocess
29                    )
30            ),
31            label => { type => SCALAR | UNDEF, optional => 1 },
32        }
33    );
34    my $label = $args{label};
35
36    my $callback
37        = ( exists $args{on_match} or exists $args{on_fail} ) ? 1 : undef;
38
39    return sub {
40        my ( $self, $date, $p, @args ) = @_;
41        return unless defined $date;
42        my %p;
43        %p = %$p if $p;    # Look! A Copy!
44
45        my %param = (
46            self => $self,
47            ( defined $label ? ( label => $label ) : () ),
48            ( @args          ? ( args  => \@args ) : () ),
49        );
50
51        # Preprocess - can modify $date and fill %p
52        if ( $args{preprocess} ) {
53            $date = $args{preprocess}
54                ->( input => $date, parsed => \%p, %param );
55        }
56
57        my $rv = $class->do_match( $date, @args ) if $class->can('do_match');
58
59        # Funky callback thing
60        if ($callback) {
61            my $type = defined $rv ? "on_match" : "on_fail";
62            $args{$type}->( input => $date, %param ) if $args{$type};
63        }
64        return unless defined $rv;
65
66        my $dt;
67        $dt = $class->post_match( $date, $rv, \%p )
68            if $class->can('post_match');
69
70        # Allow post processing. Return undef if regarded as failure
71        if ( $args{postprocess} ) {
72            my $rv = $args{postprocess}->(
73                parsed => \%p,
74                input  => $date,
75                post   => $dt,
76                %param,
77            );
78            return unless $rv;
79        }
80
81        # A successful match!
82        $dt = $class->make( $date, $dt, \%p ) if $class->can('make');
83        return $dt;
84    };
85}
86
87
88{
89    no strict 'refs';
90    for (qw( valid_params params )) {
91        *$_ = *{"DateTime::Format::Builder::Parser::$_"};
92    }
93}
94
951;
96
97# ABSTRACT: Useful routines
98
99__END__
100
101=pod
102
103=head1 NAME
104
105DateTime::Format::Builder::Parser::generic - Useful routines
106
107=head1 VERSION
108
109version 0.81
110
111=head1 METHODS
112
113=head2 Useful
114
115=head3 new
116
117Standard constructor. Returns a blessed hash; any arguments are placed
118in the hash. This is useful for storing information between methods.
119
120=head3 generic_parser
121
122This is a method provided solely for the benefit of
123C<Parser> implementations. It semi-neatly abstracts
124a lot of the work involved.
125
126Basically, it takes parameters matching the assorted
127callbacks from the parser declarations and makes a coderef
128out of it all.
129
130Currently recognized callbacks are:
131
132=over 4
133
134=item *
135
136on_match
137
138=item *
139
140on_fail
141
142=item *
143
144preprocess
145
146=item *
147
148postprocess
149
150=back
151
152=head2 Methods for subclassing
153
154These are methods you should define when writing your own subclass.
155
156B<Note>: these methods do not exist in this class. There is no point
157trying to call C<< $self->SUPER::do_match( ... ) >>.
158
159=head3 do_match
160
161C<do_match> is the first phase. Arguments are the date and @args.
162C<self>, C<label>, C<args>. Return value must be defined if you match
163successfully.
164
165=head3 post_match
166
167C<post_match> is called after the appropriate callback out of
168C<on_match>/C<on_fail> is done. It's passed the date, the return
169value from C<do_match> and the parsing hash.
170
171Its return value is used as the C<post> argument to the C<postprocess>
172callback, and as the second argument to C<make>.
173
174=head3 make
175
176C<make> takes the original input, the return value from C<post_match>
177and the parsing hash and should return a C<DateTime> object or
178undefined.
179
180=head2 Delegations
181
182For use of C<Parser>, this module also delegates C<valid_params> and
183C<params>. This is just convenience to save typing the following:
184
185    DateTime::Format::Builder::Parser->valid_params( blah )
186
187Instead we get to type:
188
189    $self->valid_params( blah );
190    __PACKAGE__->valid_params( blah );
191
192=head1 WRITING A SUBCLASS
193
194Rather than attempt to explain how it all works, I think it's best if
195you take a look at F<Regex.pm> and F<Strptime.pm> as examples and
196work from there.
197
198=head1 SUPPORT
199
200See L<DateTime::Format::Builder> for details.
201
202=head1 SEE ALSO
203
204C<datetime@perl.org> mailing list.
205
206http://datetime.perl.org/
207
208L<perl>, L<DateTime>, L<DateTime::Format::Builder>,
209L<DateTime::Format::Builder::Parser>.
210
211=head1 AUTHORS
212
213=over 4
214
215=item *
216
217Dave Rolsky <autarch@urth.org>
218
219=item *
220
221Iain Truskett
222
223=back
224
225=head1 COPYRIGHT AND LICENSE
226
227This software is Copyright (c) 2013 by Dave Rolsky.
228
229This is free software, licensed under:
230
231  The Artistic License 2.0 (GPL Compatible)
232
233=cut
234