1Params::Callback(3pm) User Contributed Perl DocumentationParams::Callback(3pm)
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 a
103 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 to
194 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 proper
236 value for the the redirected() method to return, and will still abort
237 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 Params::Callback::Exception::Abort
272 object and can thus be caught by "eval{}". The aborted() method is a
273 shortcut for determining whether an exception was generated by abort().
274
275 aborted
276
277 die $err if $cb->aborted;
278 die $err if $cb->aborted($err);
279
280 Returns true or "undef" to indicate whether the specified $err was
281 generated by abort(). If no $err argument is passed, aborted() examines
282 $@, instead.
283
284 In this code, we catch and process fatal errors while letting abort()
285 exceptions pass through:
286
287 eval { code_that_may_die_or_abort() };
288 if (my $err = $@) {
289 die $err if $cb->aborted($err);
290
291 # handle fatal errors...
292 }
293
294 $@ can lose its value quickly, so if you're planning to call
295 "$cb->aborted" more than a few lines after the "eval", you should save
296 $@ to a temporary variable and explicitly pass it to aborted() as in
297 the above example.
298
300 Under Perl 5.6.0 and later, Params::Callback offers an object-oriented
301 callback interface. The object-oriented approach is to subclass
302 Params::Callback, add the callback methods you need, and specify a
303 class key that uniquely identifies your subclass across all
304 Params::Callback subclasses in your application. The key is to use Perl
305 method attributes to identify methods as callback methods, so that
306 Params::Callback can find them and execute them when the time comes.
307 Here's an example:
308
309 package MyApp::CallbackHandler;
310 use base qw(Params::Callback);
311 use strict;
312
313 __PACKAGE__->register_subclass( class_key => 'MyHandler' );
314
315 sub build_utc_date : Callback( priority => 2 ) {
316 my $self = shift;
317 my $params = $self->params;
318 $params->{date} = sprintf "%04d-%02d-%02dT%02d:%02d:%02d",
319 delete @{$params}{qw(year month day hour minute second)};
320 }
321
322 This parameter-triggered callback can then be executed via a parameter
323 hash such as this:
324
325 my $params = { "MyHandler|build_utc_date_cb" => 1 };
326
327 Think of the part of the name preceding the pipe (the package key) as
328 the class name, and the part of the name after the pipe (the callback
329 key) as the method to call (plus '_cb'). If multiple parameters use the
330 "MyHandler" class key in a single request, then a single
331 MyApp::CallbackHandler object instance will be used to execute each of
332 those callback methods for that request.
333
334 To configure your Params::CallbackRequest object to use this callback,
335 use its "cb_classes" constructor parameter:
336
337 my $cb_request = Params::CallbackRequest->new
338 ( cb_classes => [qw(MyHandler)] );
339 $cb_request->request($params);
340
341 Now, there are a few of things to note in the above callback class
342 example. The first is the call to "__PACKAGE__->register_subclass".
343 This step is required in all callback subclasses in order that
344 Params::Callback will know about them, and thus they can be loaded into
345 an instance of a Params::CallbackRequest object via its "cb_classes"
346 constructor parameter.
347
348 Second, a callback class key must be declared for the class. This can
349 be done either by implementing the CLASS_KEY() class method or constant
350 in your subclass, or by passing the "class_key" parameter to
351 "__PACKAGE__->register_subclass", which will then create the
352 CLASS_KEY() method for you. If no callback key is declared, then
353 Params::Callback will throw an exception when you try to load your
354 subclass' callback methods into a Params::CallbackRequest object.
355
356 One other, optional parameter, "default_priority", may also be passed
357 to register_subclass(). The value of this parameter (an integer between
358 0 and 9) will be used to create a DEFAULT_PRIORITY() class method in
359 the subclass. You can also explicitly implement the DEFAULT_PRIORITY()
360 class method or constant in the subclass, if you'd rather. All
361 parameter-triggered callback methods in that class will have their
362 priorities set to the value returned by DEFAULT_PRIORITY(), unless they
363 override it via their "Callback" attributes.
364
365 And finally, notice the "Callback" attribute on the "build_utc_date"
366 method declaration in the example above. This attribute is what
367 identifies "build_utc_date" as a parameter-triggered callback. Without
368 the "Callback" attribute, any subroutine declaration in your subclass
369 will just be a subroutine or a method; it won't be a callback, and it
370 will never be executed by Params::CallbackRequest. One parameter,
371 "priority", can be passed via the "Callback" attribute. In the above
372 example, we pass "priority => 2", which sets the priority for the
373 callback. Without the "priority" parameter, the callback's priority
374 will be set to the value returned by the DEFAULT_PRIORITY() class
375 method. Of course, the priority can still be overridden by adding it to
376 the callback trigger key. For example, here we force the callback
377 priority for the execution of the "build_utc_date" callback method for
378 this one field to be the highest priority, "0":
379
380 my $params = { "MyHandler|build_utc_date_cb0" => 1 };
381
382 Other parameters to the "Callback" attribute may be added in future
383 versions of Params::Callback.
384
385 Request callbacks can also be implemented as callback methods using the
386 "PreCallback" and "PostCallback" attributes, which currently support no
387 parameters.
388
389 Subclassing Examples
390 At this point, you may be wondering what advantage the object-oriented
391 callback interface offer over functional callbacks. There are a number
392 of advantages. First, it allows you to make use of callbacks provided
393 by other users without having to reinvent the wheel for yourself. Say
394 someone has implemented the above class with its exceptionally complex
395 build_utc_date() callback method. You need to have the same
396 functionality, only with fractions of a second added to the date format
397 so that you can insert them into your database without an error. (This
398 is admittedly a contrived example, but you get the idea.) To make it
399 happen, you merely have to subclass the above class and override the
400 build_utc_date() method to do what you need:
401
402 package MyApp::Callback::Subclass;
403 use base qw(MyApp::CallbackHandler);
404 use strict;
405
406 __PACKAGE__->register_subclass;
407
408 # Implement CLASS_KEY ourselves.
409 use constant CLASS_KEY => 'SubHandler';
410
411 sub build_utc_date : Callback( priority => 1 ) {
412 my $self = shift;
413 $self->SUPER::build_utc_date;
414 my $params = $self->params;
415 $params->{date} .= '.000000';
416 }
417
418 This callback can then be triggered by a parameter hash such as this:
419
420 my $params = { "SubHandler|build_utc_date_cb" => 1 };
421
422 Note that we've used the "SubHandler" class key. If we used the
423 "MyHandler" class key, then the build_utc_date() method would be called
424 on an instance of the MyApp::CallbackHandler class, instead.
425
426 Request Callback Methods
427
428 I'll admit that the case for request callback methods is a bit more
429 tenuous. Granted, a given application may have 100s or even 1000s of
430 parameter-triggered callbacks, but only one or two request callbacks,
431 if any. But the advantage of request callback methods is that they
432 encourage code sharing, in that Params::Callback creates a kind of
433 plug-in architecture Perl templating architectures.
434
435 For example, say someone has kindly created a Params::Callback
436 subclass, Params::Callback::Unicodify, with the request callback method
437 unicodify(), which translates character sets, allowing you to always
438 store data in the database in Unicode. That's all well and good, as far
439 as it goes, but let's say that you want to make sure that your Unicode
440 strings are actually encoded using the Perl "\x{..}" notation. Again,
441 just subclass:
442
443 package Params::Callback::Unicodify::PerlEncode;
444 use base qw(Params::Callback::Unicodify);
445 use strict;
446
447 __PACKAGE__->register_subclass( class_key => 'PerlEncode' );
448
449 sub unicodify : PreCallback {
450 my $self = shift;
451 $self->SUPER::unicodify;
452 my $params = $self->params;
453 encode_unicode($params); # Hand waving.
454 }
455
456 Now you can just tell Params::CallbackRequest to use your subclassed
457 callback handler:
458
459 my $cb_request = Params::CallbackRequest->new
460 ( cb_classes => [qw(PerlEncode)] );
461
462 Yeah, okay, you could just create a second pre-callback request
463 callback to encode the Unicode characters using the Perl "\x{..}"
464 notation. But you get the idea. Better examples welcome.
465
466 Overriding the Constructor
467
468 Another advantage to using callback classes is that you can override
469 the Params::Callback new() constructor. Since every callback for a
470 single class will be executed on the same instance object in a single
471 request, you can set up object properties in the constructor that
472 subsequent callback methods in the same request can then access.
473
474 For example, say you had a series of pages that all do different things
475 to manage objects in your application. Each of those pages might have a
476 number of parameters in common to assist in constructing an object:
477
478 my $params = { class => "MyApp::Spring",
479 obj_id => 10,
480 # ...
481 };
482
483 Then the remaining parameters created for each of these pages have
484 different key/value pairs for doing different things with the object,
485 perhaps with numerous parameter-triggered callbacks. Here's where
486 subclassing comes in handy: you can override the constructor to
487 construct the object when the callback object is constructed, so that
488 each of your callback methods doesn't have to:
489
490 package MyApp::Callback;
491 use base qw(Params::Callback);
492 use strict;
493 __PACKAGE__->register_subclass( class_key => 'MyCBHandler' );
494
495 sub new {
496 my $class = shift;
497 my $self = $class->SUPER::new(@_);
498 my $params = $self->params;
499 $self->object($params->{class}->lookup( id => $params->{obj_id} ));
500 }
501
502 sub object {
503 my $self = shift;
504 if (@_) {
505 $self->{object} = shift;
506 }
507 return $self->{object};
508 }
509
510 sub save : Callback {
511 my $self = shift;
512 $self->object->save;
513 }
514
516 Much of the interface for subclassing Params::Callback is evident in
517 the above examples. Here is a reference to the complete callback
518 subclassing API.
519
520 Callback Class Declaration
521 Callback classes always subclass Params::Callback, so of course they
522 must always declare such. In addition, callback classes must always
523 call "__PACKAGE__->register_subclass" so that Params::Callback is aware
524 of them and can tell Params::CallbackRequest about them.
525
526 Second, callback classes must have a class key. The class key can be
527 created either by implementing a CLASS_KEY() class method or constant
528 that returns the class key, or by passing the "class_key" parameter to
529 register_subclass() method. If no "class_key" parameter is passed to
530 register_subclass() and no CLASS_KEY() method exists,
531 register_subclass() will create the CLASS_KEY() class method to return
532 the actual class name. So here are a few example callback class
533 declarations:
534
535 package MyApp::Callback;
536 use base qw(Params::Callback);
537 __PACKAGE__->register_subclass( class_key => 'MyCBHandler' );
538
539 In this declaration register_subclass() will create a CLASS_KEY() class
540 method returning "MyCBHandler" in the MyApp::CallbackHandler class.
541
542 package MyApp::AnotherCallback;
543 use base qw(MyApp::Callback);
544 __PACKAGE__->register_subclass;
545 use constant CLASS_KEY => 'AnotherCallback';
546
547 In this declaration, we've created an explicit CLASS_KEY() class method
548 (using the handy "use constant" syntax, so that register_subclass()
549 doesn't have to.
550
551 package MyApp::Callback::Foo;
552 use base qw(Params::Callback);
553 __PACKAGE__->register_subclass;
554
555 And in this callback class declaration, we've specified neither a
556 "class_key" parameter to register_subclass(), nor created a CLASS_KEY()
557 class method. This causes register_subclass() to create the CLASS_KEY()
558 class method returning the name of the class itself, i.e.,
559 "MyApp::FooHandler". Thus any parameter-triggered callbacks in this
560 class can be triggered by using the class name in the trigger key:
561
562 my $params = { "MyApp::Callback::Foo|take_action_cb" => 1 };
563
564 A second, optional parameter, "default_priority", may also be passed to
565 register_subclass() in order to set a default priority for all of the
566 methods in the class (and for all the methods in subclasses that don't
567 declare their own "default_priority"s):
568
569 package MyApp::Callback;
570 use base qw(Params::Callback);
571 __PACKAGE__->register_subclass( class_key => 'MyCB',
572 default_priority => 7 );
573
574 As with the "class_key" parameter, the "default_priority" parameter
575 creates a class method, DEFAULT_PRIORITY(). If you'd rather, you can
576 create this class method yourself; just be sure that its value is a
577 valid priority -- that is, an integer between "0" and "9":
578
579 package MyApp::Callback;
580 use base qw(Params::Callback);
581 use constant DEFAULT_PRIORITY => 7;
582 __PACKAGE__->register_subclass( class_key => 'MyCB' );
583
584 Any callback class that does not specify a default priority via the
585 "default_priority" or by implementing a <DEFAULT_PRIORITY()> class
586 method will simply inherit the priority returned by
587 "Params::Callback->DEFAULT_PRIORITY", which is "5".
588
589 Note: In a mod_perl environment, it's important that you "use" any and
590 all Params::Callback subclasses before you "use
591 Params::CallbackRequest". This is to get around an issue with
592 identifying the names of the callback methods in mod_perl. Read the
593 comments in the source code if you're interested in learning more.
594
595 Method Attributes
596 These method attributes are required to create callback methods in
597 Params::Callback subclasses.
598
599 Callback
600
601 sub take_action : Callback {
602 my $self = shift;
603 # Do stuff.
604 }
605
606 This attribute identifies a parameter-triggered callback method. The
607 callback key is the same as the method name ("take_action" in this
608 example). The priority for the callback may be set via an optional
609 "priority" parameter to the "Callback" attribute, like so:
610
611 sub take_action : Callback( priority => 5 ) {
612 my $self = shift;
613 # Do stuff.
614 }
615
616 Otherwise, the priority will be that returned by
617 "$self->DEFAULT_PRIORITY".
618
619 Note: The priority set via the "priority" parameter to the "Callback"
620 attribute is not inherited by any subclasses that override the callback
621 method. This may change in the future.
622
623 PreCallback
624
625 sub early_action : PreCallback {
626 my $self = shift;
627 # Do stuff.
628 }
629
630 This attribute identifies a method as a request callback that gets
631 executed for every request before any parameter-triggered callbacks are
632 executed . No parameters to "PreCallback" are currently supported.
633
634 PostCallback
635
636 sub late_action : PostCallback {
637 my $self = shift;
638 # Do stuff.
639 }
640
641 This attribute identifies a method as a request callback that gets
642 executed for every request after any parameter-triggered callbacks are
643 executed . No parameters to "PostCallback" are currently supported.
644
646 • Allow methods that override parent methods to inherit the parent
647 method's priority?
648
650 Params::CallbackRequest constructs Params::Callback objects and
651 executes the appropriate callback functions and/or methods. It's worth
652 a read.
653
655 This module is stored in an open repository at the following address:
656
657 <https://svn.kineticode.com/Params-CallbackRequest/trunk/>
658
659 Patches against Params::CallbackRequest are welcome. Please send bug
660 reports to <bug-params-callbackrequest@rt.cpan.org>.
661
663 David E. Wheeler <david@justatheory.com>
664
666 Copyright 2003-2011 David E. Wheeler. Some Rights Reserved.
667
668 This library is free software; you can redistribute it and/or modify it
669 under the same terms as Perl itself.
670
671
672
673perl v5.38.0 2023-07-21 Params::Callback(3pm)