1Params::Callback(3) User Contributed Perl Documentation Params::Callback(3)
2
3
4
6 Params::Callback - Parameter callback base class
7
9 Functional callback interface:
10
11 sub my_callback {
12 # Sole argument is a Params::Callback object.
13 my $cb = shift;
14 my $params = $cb->params;
15 my $value = $cb->value;
16 # Do stuff with above data.
17 }
18
19 Object-oriented callback interface:
20
21 package MyApp::Callback;
22 use base qw(Params::Callback);
23 use constant CLASS_KEY => 'MyHandler';
24 use strict;
25
26 sub my_callback : Callback {
27 my $self = shift;
28 my $params = $self->params;
29 my $value = $self->value;
30 # Do stuff with above data.
31 }
32
34 Params::Callback provides the interface for callbacks to access
35 parameter hashes Params::CallbackRequest object, and callback metadata,
36 as well as for executing common request actions, such as aborting a
37 callback execution request. There are two ways to use Params::Callback:
38 via functional-style callback subroutines and via object-oriented
39 callback methods.
40
41 For functional callbacks, a Params::Callback object is constructed by
42 Params::CallbackRequest for each call to its "request()" method, and
43 passed as the sole argument for every execution of a callback function.
44 See Params::CallbackRequest for details on how to create a
45 Params::CallbackRequest object to execute your callback code.
46
47 In the object-oriented callback interface, Params::Callback is the
48 parent class from which all callback classes inherit. Callback methods
49 are declared in such subclasses via "Callback", "PreCallback", and
50 "PostCallback" attributes to each method declaration. Methods and
51 subroutines declared without one of these callback attributes are not
52 callback methods, but normal methods or subroutines of the subclass.
53 Read subclassing for details on subclassing Params::Callback.
54
56 Params::Callback provides the parameter hash accessors and utility
57 methods that will help manage a callback request (where a "callback
58 request" is considered a single call to the "request()" method on a
59 Params::CallbackRequest object). Functional callbacks always get a
60 Params::Callback object passed as their first argument; the same
61 Params::Callback object will be used for all callbacks in a single
62 request. For object-oriented callback methods, the first argument will
63 of course always be an object of the class corresponding to the class
64 key used in the callback key (or, for request callback methods, an
65 instance of the class for which the request callback method was
66 loaded), and the same object will be reused for all subsequent
67 callbacks to the same class in a single request.
68
69 Accessor Methods
70 All of the Params::Callback accessor methods are read-only. Feel free
71 to add other attributes in your Params::Callback subclasses if you're
72 using the object-oriented callback interface.
73
74 cb_request
75
76 my $cb_request = $cb->cb_request;
77
78 Returns a reference to the Params::CallbackRequest object that executed
79 the callback.
80
81 params
82
83 my $params = $cb->params;
84
85 Returns a reference to the request parameters hash. Any changes you
86 make to this hash will propagate beyond the lifetime of the request.
87
88 apache_req
89
90 my $r = $cb->apache_req;
91
92 Returns the Apache request object for the current request, provided
93 you've passed one to "Params::CallbackRequest->request". This will be
94 most useful in a mod_perl environment, of course. Use
95 Apache:FakeRequest in tests to emmulate the behavior of an Apache
96 request object.
97
98 requester
99
100 my $r = $cb->requester;
101
102 Returns the object that executed the callback by calling "request()" on
103 a Params::CallbackRequest object. Only available if the "requester"
104 parameter is passed to "Params::CallbackRequest->request". This can be
105 useful for callbacks to get access to the object that executed the
106 callbacks.
107
108 priority
109
110 my $priority = $cb->priority;
111
112 Returns the priority level at which the callback was executed. Possible
113 values range from "0" to "9", and may be set by a default priority
114 setting, by the callback configuration or method declaration, or by the
115 parameter callback trigger key. See Params::CallbackRequest for
116 details.
117
118 cb_key
119
120 my $cb_key = $cb->cb_key;
121
122 Returns the callback key that triggered the execution of the callback.
123 For example, this callback-triggering parameter hash:
124
125 my $params = { "DEFAULT|save_cb" => 'Save' };
126
127 Will cause the "cb_key()" method in the relevant callback to return
128 "save".
129
130 pkg_key
131
132 my $pkg_key = $cb->pkg_key;
133
134 Returns the package key used in the callback trigger parameter key. For
135 example, this callback-triggering parameter hash:
136
137 my $params = { "MyCBs|save_cb" => 'Save' };
138
139 Will cause the "pkg_key()" method in the relevant callback to return
140 "MyCBs".
141
142 class_key
143
144 my $class_key = $cb->class_key;
145
146 An alias for "pkg_key", only perhaps a bit more appealing for use in
147 object-oriented callback methods.
148
149 trigger_key
150
151 my $trigger_key = $cb->trigger_key;
152
153 Returns the complete parameter key that triggered the callback. For
154 example, if the parameter key that triggered the callback looks like
155 this:
156
157 my $params = { "MyCBs|save_cb6" => 'Save' };
158
159 Then the value returned by "trigger_key()" method will be
160 "MyCBs|save_cb6".
161
162 Note: Most browsers will submit "image" input fields with two
163 arguments, one with ".x" appended to its name, and the other with ".y"
164 appended to its name. Because Params::CallbackRequest is designed to be
165 used with Web form fields populating a parameter hash, it will ignore
166 these fields and either use the field that's named without the ".x" or
167 ".y", or create a field with that name and give it a value of "1". The
168 reasoning behind this approach is that the names of the callback-
169 triggering fields should be the same as the names that appear in the
170 HTML form fields. If you want the actual x and y image click
171 coordinates, access them directly from the request parameters:
172
173 my $params = $cb->params;
174 my $trigger_key = $cb->trigger_key;
175 my $x = $params->{"$trigger_key.x"};
176 my $y = $params->{"$trigger_key.y"};
177
178 value
179
180 my $value = $cb->value;
181
182 Returns the value of the parameter that triggered the callback. This
183 value can be anything that can be stored in a hash value -- that is,
184 any scalar value. Thus, in this example:
185
186 my $params = { "DEFAULT|save_cb" => 'Save',
187 "DEFAULT|open_cb" => [qw(one two)] };
188
189 "value()" will return the string "Save" in the save callback, but the
190 array reference "['one', 'two']" in the open callback.
191
192 Although you may often be able to retrieve the value directly from the
193 hash reference returned by "params()", if multiple callback keys point
194 to the same subroutine or if the parameter that triggered the callback
195 overrode the priority, you may not be able to determine which value was
196 submitted for a particular callback execution. So Params::Callback
197 kindly provides the value for you. The exception to this rule is values
198 submitted under keys named for HTML "image" input fields. See the note
199 about this under the documentation for the "trigger_key()" method.
200
201 redirected
202
203 $cb->redirect($url) unless $cb->redirected;
204
205 If the request has been redirected, this method returns the redirection
206 URL. Otherwise, it returns false. This method is useful for conditions
207 in which one callback has called "$cb->redirect" with the optional
208 $wait argument set to a true value, thus allowing subsequent callbacks
209 to continue to execute. If any of those subsequent callbacks want to
210 call "$cb->redirect" themselves, they can check the value of
211 "$cb->redirected" to make sure it hasn't been done already.
212
213 Other Methods
214 Params::Callback offers has a few other publicly accessible methods.
215
216 notes
217
218 $cb->notes($key => $value);
219 my $val = $cb->notes($key);
220 my $notes = $cb->notes;
221
222 Shortcut for "$cb->cb_request->notes". It provides a place to store
223 application data, giving developers a way to share data among multiple
224 callbacks. See "notes()" for more information.
225
226 redirect
227
228 $cb->redirect($url);
229 $cb->redirect($url, $wait);
230 $cb->redirect($url, $wait, $status);
231
232 This method can be used to redirect a request in a mod_perl
233 environment, provided that an Apache request object has been passed to
234 "Params::CallbackRequest->new". Outide of a mod_perl environment or
235 without an Apache request object, "redirect()" will still set the
236 proper value for the the "redirected()" method to return, and will
237 still abort the callback request.
238
239 Given a URL, this method generates a proper HTTP redirect for that URL.
240 By default, the status code used is "302", but this can be overridden
241 via the $status argument. If the optional $wait argument is true, any
242 callbacks scheduled to be executed after the call to "redirect" will
243 continue to be executed. In that case, "$cb->abort" will not be called;
244 rather, Params::CallbackRequest will finish executing all remaining
245 callbacks and then return the abort status. If the $wait argument is
246 unspecified or false, then the request will be immediately terminated
247 without executing subsequent callbacks or. This approach relies on the
248 execution of "$cb->abort".
249
250 Since "$cb->redirect" calls "$cb->abort", it will be trapped by an
251 "eval {}" block. If you are using an "eval {}" block in your code to
252 trap exceptions, you need to make sure to rethrow these exceptions,
253 like this:
254
255 eval {
256 ...
257 };
258
259 die $@ if $cb->aborted;
260
261 # handle other exceptions
262
263 abort
264
265 $cb->abort($status);
266
267 Aborts the current request without executing any more callbacks. The
268 $status argument specifies a request status code to be returned to by
269 "Params::CallbackRequest->request()".
270
271 "abort()" is implemented by throwing a
272 Params::Callback::Exception::Abort object and can thus be caught by
273 "eval{}". The "aborted()" method is a shortcut for determining whether
274 an exception was generated by "abort()".
275
276 aborted
277
278 die $err if $cb->aborted;
279 die $err if $cb->aborted($err);
280
281 Returns true or "undef" to indicate whether the specified $err was
282 generated by "abort()". If no $err argument is passed, "aborted()"
283 examines $@, instead.
284
285 In this code, we catch and process fatal errors while letting "abort()"
286 exceptions pass through:
287
288 eval { code_that_may_die_or_abort() };
289 if (my $err = $@) {
290 die $err if $cb->aborted($err);
291
292 # handle fatal errors...
293 }
294
295 $@ can lose its value quickly, so if you're planning to call
296 "$cb->aborted" more than a few lines after the "eval", you should save
297 $@ to a temporary variable and explicitly pass it to "aborted()" as in
298 the above example.
299
301 Under Perl 5.6.0 and later, Params::Callback offers an object-oriented
302 callback interface. The object-oriented approach is to subclass
303 Params::Callback, add the callback methods you need, and specify a
304 class key that uniquely identifies your subclass across all
305 Params::Callback subclasses in your application. The key is to use Perl
306 method attributes to identify methods as callback methods, so that
307 Params::Callback can find them and execute them when the time comes.
308 Here's an example:
309
310 package MyApp::CallbackHandler;
311 use base qw(Params::Callback);
312 use strict;
313
314 __PACKAGE__->register_subclass( class_key => 'MyHandler' );
315
316 sub build_utc_date : Callback( priority => 2 ) {
317 my $self = shift;
318 my $params = $self->params;
319 $params->{date} = sprintf "%04d-%02d-%02dT%02d:%02d:%02d",
320 delete @{$params}{qw(year month day hour minute second)};
321 }
322
323 This parameter-triggered callback can then be executed via a parameter
324 hash such as this:
325
326 my $params = { "MyHandler|build_utc_date_cb" => 1 };
327
328 Think of the part of the name preceding the pipe (the package key) as
329 the class name, and the part of the name after the pipe (the callback
330 key) as the method to call (plus '_cb'). If multiple parameters use the
331 "MyHandler" class key in a single request, then a single
332 MyApp::CallbackHandler object instance will be used to execute each of
333 those callback methods for that request.
334
335 To configure your Params::CallbackRequest object to use this callback,
336 use its "cb_classes" constructor parameter:
337
338 my $cb_request = Params::CallbackRequest->new
339 ( cb_classes => [qw(MyHandler)] );
340 $cb_request->request($params);
341
342 Now, there are a few of things to note in the above callback class
343 example. The first is the call to "__PACKAGE__->register_subclass".
344 This step is required in all callback subclasses in order that
345 Params::Callback will know about them, and thus they can be loaded into
346 an instance of a Params::CallbackRequest object via its "cb_classes"
347 constructor parameter.
348
349 Second, a callback class key must be declared for the class. This can
350 be done either by implementing the "CLASS_KEY()" class method or
351 constant in your subclass, or by passing the "class_key" parameter to
352 "__PACKAGE__->register_subclass", which will then create the
353 "CLASS_KEY()" method for you. If no callback key is declared, then
354 Params::Callback will throw an exception when you try to load your
355 subclass' callback methods into a Params::CallbackRequest object.
356
357 One other, optional parameter, "default_priority", may also be passed
358 to "register_subclass()". The value of this parameter (an integer
359 between 0 and 9) will be used to create a "DEFAULT_PRIORITY()" class
360 method in the subclass. You can also explicitly implement the
361 "DEFAULT_PRIORITY()" class method or constant in the subclass, if you'd
362 rather. All parameter-triggered callback methods in that class will
363 have their priorities set to the value returned by
364 "DEFAULT_PRIORITY()", unless they override it via their "Callback"
365 attributes.
366
367 And finally, notice the "Callback" attribute on the "build_utc_date"
368 method declaration in the example above. This attribute is what
369 identifies "build_utc_date" as a parameter-triggered callback. Without
370 the "Callback" attribute, any subroutine declaration in your subclass
371 will just be a subroutine or a method; it won't be a callback, and it
372 will never be executed by Params::CallbackRequest. One parameter,
373 "priority", can be passed via the "Callback" attribute. In the above
374 example, we pass "priority => 2", which sets the priority for the
375 callback. Without the "priority" parameter, the callback's priority
376 will be set to the value returned by the "DEFAULT_PRIORITY()" class
377 method. Of course, the priority can still be overridden by adding it to
378 the callback trigger key. For example, here we force the callback
379 priority for the execution of the "build_utc_date" callback method for
380 this one field to be the highest priority, "0":
381
382 my $params = { "MyHandler|build_utc_date_cb0" => 1 };
383
384 Other parameters to the "Callback" attribute may be added in future
385 versions of Params::Callback.
386
387 Request callbacks can also be implemented as callback methods using the
388 "PreCallback" and "PostCallback" attributes, which currently support no
389 parameters.
390
391 Subclassing Examples
392 At this point, you may be wondering what advantage the object-oriented
393 callback interface offer over functional callbacks. There are a number
394 of advantages. First, it allows you to make use of callbacks provided
395 by other users without having to reinvent the wheel for yourself. Say
396 someone has implemented the above class with its exceptionally complex
397 "build_utc_date()" callback method. You need to have the same
398 functionality, only with fractions of a second added to the date format
399 so that you can insert them into your database without an error. (This
400 is admittedly a contrived example, but you get the idea.) To make it
401 happen, you merely have to subclass the above class and override the
402 "build_utc_date()" method to do what you need:
403
404 package MyApp::Callback::Subclass;
405 use base qw(MyApp::CallbackHandler);
406 use strict;
407
408 __PACKAGE__->register_subclass;
409
410 # Implement CLASS_KEY ourselves.
411 use constant CLASS_KEY => 'SubHandler';
412
413 sub build_utc_date : Callback( priority => 1 ) {
414 my $self = shift;
415 $self->SUPER::build_utc_date;
416 my $params = $self->params;
417 $params->{date} .= '.000000';
418 }
419
420 This callback can then be triggered by a parameter hash such as this:
421
422 my $params = { "SubHandler|build_utc_date_cb" => 1 };
423
424 Note that we've used the "SubHandler" class key. If we used the
425 "MyHandler" class key, then the "build_utc_date()" method would be
426 called on an instance of the MyApp::CallbackHandler class, instead.
427
428 Request Callback Methods
429
430 I'll admit that the case for request callback methods is a bit more
431 tenuous. Granted, a given application may have 100s or even 1000s of
432 parameter-triggered callbacks, but only one or two request callbacks,
433 if any. But the advantage of request callback methods is that they
434 encourage code sharing, in that Params::Callback creates a kind of
435 plug-in architecture Perl templating architectures.
436
437 For example, say someone has kindly created a Params::Callback
438 subclass, Params::Callback::Unicodify, with the request callback method
439 "unicodify()", which translates character sets, allowing you to always
440 store data in the database in Unicode. That's all well and good, as far
441 as it goes, but let's say that you want to make sure that your Unicode
442 strings are actually encoded using the Perl "\x{..}" notation. Again,
443 just subclass:
444
445 package Params::Callback::Unicodify::PerlEncode;
446 use base qw(Params::Callback::Unicodify);
447 use strict;
448
449 __PACKAGE__->register_subclass( class_key => 'PerlEncode' );
450
451 sub unicodify : PreCallback {
452 my $self = shift;
453 $self->SUPER::unicodify;
454 my $params = $self->params;
455 encode_unicode($params); # Hand waving.
456 }
457
458 Now you can just tell Params::CallbackRequest to use your subclassed
459 callback handler:
460
461 my $cb_request = Params::CallbackRequest->new
462 ( cb_classes => [qw(PerlEncode)] );
463
464 Yeah, okay, you could just create a second pre-callback request
465 callback to encode the Unicode characters using the Perl "\x{..}"
466 notation. But you get the idea. Better examples welcome.
467
468 Overriding the Constructor
469
470 Another advantage to using callback classes is that you can override
471 the Params::Callback "new()" constructor. Since every callback for a
472 single class will be executed on the same instance object in a single
473 request, you can set up object properties in the constructor that
474 subsequent callback methods in the same request can then access.
475
476 For example, say you had a series of pages that all do different things
477 to manage objects in your application. Each of those pages might have a
478 number of parameters in common to assist in constructing an object:
479
480 my $params = { class => "MyApp::Spring",
481 obj_id => 10,
482 # ...
483 };
484
485 Then the remaining parameters created for each of these pages have
486 different key/value pairs for doing different things with the object,
487 perhaps with numerous parameter-triggered callbacks. Here's where
488 subclassing comes in handy: you can override the constructor to
489 construct the object when the callback object is constructed, so that
490 each of your callback methods doesn't have to:
491
492 package MyApp::Callback;
493 use base qw(Params::Callback);
494 use strict;
495 __PACKAGE__->register_subclass( class_key => 'MyCBHandler' );
496
497 sub new {
498 my $class = shift;
499 my $self = $class->SUPER::new(@_);
500 my $params = $self->params;
501 $self->object($params->{class}->lookup( id => $params->{obj_id} ));
502 }
503
504 sub object {
505 my $self = shift;
506 if (@_) {
507 $self->{object} = shift;
508 }
509 return $self->{object};
510 }
511
512 sub save : Callback {
513 my $self = shift;
514 $self->object->save;
515 }
516
518 Much of the interface for subclassing Params::Callback is evident in
519 the above examples. Here is a reference to the complete callback
520 subclassing API.
521
522 Callback Class Declaration
523 Callback classes always subclass Params::Callback, so of course they
524 must always declare such. In addition, callback classes must always
525 call "__PACKAGE__->register_subclass" so that Params::Callback is aware
526 of them and can tell Params::CallbackRequest about them.
527
528 Second, callback classes must have a class key. The class key can be
529 created either by implementing a "CLASS_KEY()" class method or constant
530 that returns the class key, or by passing the "class_key" parameter to
531 "register_subclass()" method. If no "class_key" parameter is passed to
532 "register_subclass()" and no "CLASS_KEY()" method exists,
533 "register_subclass()" will create the "CLASS_KEY()" class method to
534 return the actual class name. So here are a few example callback class
535 declarations:
536
537 package MyApp::Callback;
538 use base qw(Params::Callback);
539 __PACKAGE__->register_subclass( class_key => 'MyCBHandler' );
540
541 In this declaration "register_subclass()" will create a "CLASS_KEY()"
542 class method returning "MyCBHandler" in the MyApp::CallbackHandler
543 class.
544
545 package MyApp::AnotherCallback;
546 use base qw(MyApp::Callback);
547 __PACKAGE__->register_subclass;
548 use constant CLASS_KEY => 'AnotherCallback';
549
550 In this declaration, we've created an explicit "CLASS_KEY()" class
551 method (using the handy "use constant" syntax, so that
552 "register_subclass()" doesn't have to.
553
554 package MyApp::Callback::Foo;
555 use base qw(Params::Callback);
556 __PACKAGE__->register_subclass;
557
558 And in this callback class declaration, we've specified neither a
559 "class_key" parameter to "register_subclass()", nor created a
560 "CLASS_KEY()" class method. This causes "register_subclass()" to create
561 the "CLASS_KEY()" class method returning the name of the class itself,
562 i.e., "MyApp::FooHandler". Thus any parameter-triggered callbacks in
563 this class can be triggered by using the class name in the trigger key:
564
565 my $params = { "MyApp::Callback::Foo|take_action_cb" => 1 };
566
567 A second, optional parameter, "default_priority", may also be passed to
568 "register_subclass()" in order to set a default priority for all of the
569 methods in the class (and for all the methods in subclasses that don't
570 declare their own "default_priority"s):
571
572 package MyApp::Callback;
573 use base qw(Params::Callback);
574 __PACKAGE__->register_subclass( class_key => 'MyCB',
575 default_priority => 7 );
576
577 As with the "class_key" parameter, the "default_priority" parameter
578 creates a class method, "DEFAULT_PRIORITY()". If you'd rather, you can
579 create this class method yourself; just be sure that its value is a
580 valid priority -- that is, an integer between "0" and "9":
581
582 package MyApp::Callback;
583 use base qw(Params::Callback);
584 use constant DEFAULT_PRIORITY => 7;
585 __PACKAGE__->register_subclass( class_key => 'MyCB' );
586
587 Any callback class that does not specify a default priority via the
588 "default_priority" or by implementing a <DEFAULT_PRIORITY()> class
589 method will simply inherit the priority returned by
590 "Params::Callback->DEFAULT_PRIORITY", which is "5".
591
592 Note: In a mod_perl environment, it's important that you "use" any and
593 all Params::Callback subclasses before you "use
594 Params::CallbackRequest". This is to get around an issue with
595 identifying the names of the callback methods in mod_perl. Read the
596 comments in the source code if you're interested in learning more.
597
598 Method Attributes
599 These method attributes are required to create callback methods in
600 Params::Callback subclasses.
601
602 Callback
603
604 sub take_action : Callback {
605 my $self = shift;
606 # Do stuff.
607 }
608
609 This attribute identifies a parameter-triggered callback method. The
610 callback key is the same as the method name ("take_action" in this
611 example). The priority for the callback may be set via an optional
612 "priority" parameter to the "Callback" attribute, like so:
613
614 sub take_action : Callback( priority => 5 ) {
615 my $self = shift;
616 # Do stuff.
617 }
618
619 Otherwise, the priority will be that returned by
620 "$self->DEFAULT_PRIORITY".
621
622 Note: The priority set via the "priority" parameter to the "Callback"
623 attribute is not inherited by any subclasses that override the callback
624 method. This may change in the future.
625
626 PreCallback
627
628 sub early_action : PreCallback {
629 my $self = shift;
630 # Do stuff.
631 }
632
633 This attribute identifies a method as a request callback that gets
634 executed for every request before any parameter-triggered callbacks are
635 executed . No parameters to "PreCallback" are currently supported.
636
637 PostCallback
638
639 sub late_action : PostCallback {
640 my $self = shift;
641 # Do stuff.
642 }
643
644 This attribute identifies a method as a request callback that gets
645 executed for every request after any parameter-triggered callbacks are
646 executed . No parameters to "PostCallback" are currently supported.
647
649 ยท Allow methods that override parent methods to inherit the parent
650 method's priority?
651
653 Params::CallbackRequest constructs Params::Callback objects and
654 executes the appropriate callback functions and/or methods. It's worth
655 a read.
656
658 This module is stored in an open repository at the following address:
659
660 <https://svn.kineticode.com/Params-CallbackRequest/trunk/>
661
662 Patches against Params::CallbackRequest are welcome. Please send bug
663 reports to <bug-params-callbackrequest@rt.cpan.org>.
664
666 David E. Wheeler <david@justatheory.com>
667
669 Copyright 2003-2011 David E. Wheeler. Some Rights Reserved.
670
671 This library is free software; you can redistribute it and/or modify it
672 under the same terms as Perl itself.
673
674
675
676perl v5.32.0 2020-07-28 Params::Callback(3)