Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Params::CallbackRequesUser Contributed Perl DocumentParams::CallbackRequest(3)

       Params::CallbackRequest - Functional and	object-oriented	callback

       Functional parameter-triggered callbacks:

	 use strict;
	 use Params::CallbackRequest;

	 # Create a callback function.
	 sub calc_time {
	     my	$cb = shift;
	     my	$params	= $cb->params;
	     my	$val = $cb->value;
	     $params->{my_time}	= localtime($val || time);

	 # Set up a callback request object.
	 my $cb_request	= Params::CallbackRequest->new(
	     callbacks => [ { cb_key  => 'calc_time',
			      pkg_key => 'myCallbacker',
			      cb      => \&calc_time } ]

	 # Request callback execution.
	 my %params = ('myCallbacker|calc_time_cb' => 1);

	 # Demonstrate the result.
	 print "The time is $params{my_time}\n";

       Or, in a	subclass of Params::Callback:

	 package MyApp::Callback;
	 use base qw(Params::Callback);
	 __PACKAGE__->register_subclass( class_key => 'myCallbacker' );

	 # Set up a callback method.
	 sub calc_time : Callback {
	     my	$self =	shift;
	     my	$params	= $self->request_params;
	     my	$val = $cb->value;
	     $params->{my_time}	= localtime($val || time);

       And then, in your application:

	 # Load	order is important here!
	 use MyApp::Callback;
	 use Params::CallbackRequest;

	 my $cb_request	= Params::Callback->new( cb_classes => [qw(myCallbacker)] );
	 my %params = ('myCallbacker|calc_time_cb' => 1);
	 print "The time is $params{my_time}\n";

       Params::CallbackRequest provides	functional and object-oriented
       callbacks to method and function	parameters. Callbacks may be either
       code references provided	to the "new()" constructor, or methods defined
       in subclasses of	Params::Callback. Callbacks are	triggered either for
       every call to the Params::CallbackRequest "request()" method, or	by
       specially named keys in the parameters to "request()".

       The idea	behind this module is to provide a sort	of plugin architecture
       for Perl	templating systems. Callbacks are triggered by the contents of
       a request to the	Perl templating	server,	before the templating system
       itself executes.	 This approach allows you to carry out logical
       processing of data submitted from a form, to affect the contents	of the
       request parameters before they're passed	to the templating system for
       processing, and even to redirect	or abort the request before the
       templating system handles it.

       Why would you want to do	this? Well, there are a	number of reasons.
       Some I can think	of offhand include:

       Stricter	separation of logic from presentation
	   While some Perl templating systems enforce separation of
	   application logic from presentation (e.g., TT, HTML::Template),
	   others do not (e.g.,	HTML::Mason, Apache::ASP). Even	in the former
	   case, application logic is often put	into scripts that are executed
	   alongside the presentation templates, and loaded on-demand under
	   mod_perl. By	moving the application logic into Perl modules and
	   then	directing the templating system	to execute that	code as
	   callbacks, you obviously benefit from a cleaner separation of
	   application logic and presentation.

	   Thanks to their ability to preprocess parameters, callbacks enable
	   developers to develop easier-to-use,	more dynamic widgets that can
	   then	be used	in any and all templating systems. For example,	a
	   widget that puts many related fields	into a form (such as a date
	   selection widget) can have its fields preprocessed by a callback
	   (for	example, to properly combine the fields	into a unified date
	   parameter) before the template that responds	to the form submission
	   gets	the data. See Params::Callback for an example solution for
	   this	very problem.

       Shared Memory
	   If you run your templating system under mod_perl, callbacks are
	   just	Perl subroutines in modules loaded at server startup time.
	   Thus	the memory they	consume	is all in the Apache parent process,
	   and shared by the child processes. For code that executes
	   frequently, this can	be much	less resource-intensive	than code in
	   templates, since templates are loaded separately in each Apache
	   child process on demand.

	   Since they're executed before the templating	architecture does much
	   processing, callbacks have the opportunity to short-circuit the
	   template processing by doing	something else.	A good example is
	   redirection.	Often the application logic in callbacks does its
	   thing and then redirects the	user to	a different page. Executing
	   the redirection in a	callback eliminates a lot of extraneous
	   processing that would otherwise be executed before the redirection,
	   creating a snappier response	for the	user.

	   Templating system templates are not easy to test via	a testing
	   framework such as Test::Harness. Subroutines	in modules, on the
	   other hand, are fully testable. This	means that you can write tests
	   in your application test suite to test your callback	subroutines.

       And if those aren't enough reasons, then	just consider this: Callbacks
       are just	way cool.

       Params::CallbackRequest supports	two different types of callbacks:
       those triggered by a specially named parameter keys, and	those executed
       for every request.

   Parameter-Triggered Callbacks
       Parameter-triggered callbacks are triggered by specially	named
       parameter keys. These keys are constructed as follows: The package name
       followed	by a pipe character ("|"), the callback	key with the string
       "_cb" appended to it, and finally an optional priority number at	the
       end. For	example, if you	specified a callback with the callback key
       "save" and the package key "world", a callback field might be specified
       like this:

	 my $params = {	"world|save_cb"	=> 'Save World'	};

       When the	parameters hash	$params	is passed to Params::CallbackRequest's
       "request()" method, the "world|save_cb" parameter would trigger the
       callback	associated with	the "save" callback key	in the "world"
       package.	If such	a callback hasn't been configured, then
       Params::CallbackRequest will throw a
       Params::CallbackRequest::Exceptions::InvalidKey exception. Here's how
       to configure a functional callback when constructing your
       Params::CallbackRequest object so that that doesn't happen:

	 my $cb_request	= Params::CallbackRequest->new
	   ( callbacks => [ { pkg_key => 'world',
			      cb_key  => 'save',
			      cb      => \&My::World::save } ] );

       With this configuration,	the "world|save_cb" parameter key will trigger
       the execution of	the "My::World::save()"	subroutine during a callback

	 # Execute parameter-triggered callback.

       Functional Callback Subroutines

       Functional callbacks use	a code reference for parameter-triggered
       callbacks, and Params::CallbackRequest executes them with a single
       argument, a Params::Callback object. Thus, a callback subroutine	will
       generally look something	like this:

	 sub foo {
	     my	$cb = shift;
	     # Do stuff.

       The Params::Callback object provides accessors to data relevant to the
       callback, including the callback	key, the package key, and the
       parameter hash. It also includes	an "abort()" method. See the
       Params::Callback	documentation for all the goodies.

       Note that Params::CallbackRequest installs an exception handler during
       the execution of	callbacks, so if any of	your callback subroutines
       "die", Params::CallbackRequest will throw an
       Params::Callback::Exception::Execution exception. If your callback
       subroutines throw their own exception objects, Params::CallbackRequest
       will simply rethrow them. If you	don't like this	configuration, use the
       "exception_handler" parameter to	"new()"	to install your	own exception

       Object-Oriented Callback	Methods

       Object-oriented callback	methods, which are supported under Perl	5.6 or
       later, are defined in subclasses	of Params::Callback, and identified by
       attributes in their declarations. Unlike	functional callbacks, callback
       methods are not called with a Params::Callback object, but with an
       instance	of the callback	subclass. These	classes	inherit	all the
       goodies provided	by Params::Callback, so	you can	essentially use	their
       instances exactly as you	would use the Params::Callback object in
       functional callback subroutines.	But because they're subclasses,	you
       can add your own	methods	and attributes.	See Params::Callback for all
       the gory	details	on subclassing,	along with a few examples. Generally,
       callback	methods	will look like this:

	 sub foo : Callback {
	     my	$self =	shift;
	     # Do stuff.

       As with functional callback subroutines,	method callbacks are executed
       with a custom exception handler.	Again, see the "exception_handler"
       parameter to install your own exception handler.

       Note: Under mod_perl, it's important that you "use" any and all
       Params::Callback	subclasses before you "use Params::CallbackRequest".
       This is to get around an	issue with identifying the names of the
       callback	methods	in mod_perl. Read the comments in the Params::Callback
       source code if you're interested	in learning more.

       The Package Key

       The use of the package key is a convenience so that a system with many
       functional callbacks can	use callbacks with the same keys but in
       different packages. The idea is that the	package	key will uniquely
       identify	the module in which each callback subroutine is	found, but it
       doesn't necessarily have	to be so. Use the package key any way you
       wish, or	not at all:

	 my $cb_request	= Params::CallbackRequest->new
	   ( callbacks => [ { cb_key  => 'save',
			      cb      => \&My::World::save } ] );

       But note	that if	you don't specify the package key, you'll still	need
       to provide one in the parameter hash passed to "request()". By default,
       that key	is "DEFAULT". Such a callback parameter	would then look	like

	 my $params = {	"DEFAULT|save_cb" => 'Save World' };

       If you don't like the "DEFAULT" package name, you can set an
       alternative default using the "default_pkg_name"	parameter to "new()":

	 my $cb_request	= Params::CallbackRequest->new
	   ( callbacks	      => [ { cb_key  =>	'save',
				     cb	     =>	\&My::World::save } ],
	     default_pkg_name => 'MyPkg' );

       Then, of	course,	any callbacks without a	specified package key of their
       own must	then use the custom default:

	 my $params = {	"MyPkg|save_cb"	=> 'Save World'	};

       The Class Key

       The class key is	essentially a synonym for the package key, but applies
       more directly to	object-oriented	callbacks. The difference is mainly
       that it corresponds to an actual	class, and that	all Params::Callback
       subclasses are required to have a class key; it's not optional as it is
       with functional callbacks. The class key	may be declared	in your
       Params::Callback	subclass like so:

	 package MyApp::CallbackHandler;
	 use base qw(Params::Callback);
	 __PACKAGE__->register_subclass( class_key => 'MyCBHandler' );

       The class key can also be declared by implementing a "CLASS_KEY"
       subroutine, like	so:

	 package MyApp::CallbackHandler;
	 use base qw(Params::Callback);
	 use constant CLASS_KEY	=> 'MyCBHandler';

       If no class key is explicitly defined, Params::Callback will use	the
       subclass	name, instead. In any event, the "register_callback()" method
       must be called to register the subclass with Params::Callback. See the
       Params::Callback	documentation for complete details.


       Sometimes one callback is more important	than another. For example, you
       might rely on the execution of one callback to set up variables needed
       by another.  Since you can't rely on the	order in which callbacks are
       executed	(the parameters	are passed via a hash, and the processing of a
       hash is,	of course, unordered), you need	a method of ensuring that the
       setup callback executes first.

       In such a case, you can set a higher priority level for the setup
       callback	than for callbacks that	depend on it. For functional
       callbacks, you can do it	like this:

	 my $cb_request	= Params::CallbackRequest->new
	   ( callbacks	      => [ { cb_key   => 'setup',
				     priority => 3,
				     cb	      => \&setup },
				   { cb_key   => 'save',
				     cb	      => \&save	}
				 ] );

       For object-oriented callbacks, you can define the priority right	in the
       callback	method declaration:

	 sub setup : Callback( priority	=> 3 ) {
	     my	$self =	shift;
	     # ...

	 sub save : Callback {
	     my	$self =	shift;
	     # ...

       In these	examples, the "setup" callback has been	configured with	a
       priority	level of "3". This ensures that	it will	always execute before
       the "save" callback, which has the default priority of "5". Obviously,
       this is true regardless of the order of the fields in the hash:

	 my $params = {	"DEFAULT|save_cb"  => 'Save World',
			"DEFAULT|setup_cb" => 1	};

       In this configuration, the "setup" callback will	always execute first
       because of its higher priority.

       Although	the "save" callback got	the default priority of	"5", this too
       can be customized to a different	priority level via the
       "default_priority" parameter to "new()" for functional callbacks	and
       the "default_priority" to the class declaration for object-oriented
       callbacks. For example, this functional callback	configuration:

	 my $cb_request	= Params::CallbackRequest->new
	   ( callbacks	      => [ { cb_key   => 'setup',
				     priority => 3,
				     cb	      => \&setup },
				   { cb_key   => 'save',
				     cb	      => \&save	}
	     default_priority => 2 );

       Or this Params::Callback	subclass declaration:

	 package MyApp::CallbackHandler;
	 use base qw(Params::Callback);
	 __PACKAGE__->register_subclass( class_key	  => 'MyCBHandler',
					 default_priority => 2 );

       Will cause the "save" callback to always	execute	before the "setup"
       callback, since its priority level will default to "2".

       In addition, the	priority level can be overridden via the parameter key
       itself by appending a priority level to the end of the key name.	Hence,
       this example:

	 my $params = {	"DEFAULT|save_cb2" => 'Save World',
			"DEFAULT|setup_cb" => 1	};

       Causes the "save" callback to execute before the	"setup"	callback by
       overriding the "save" callback's	priority to level "2". Of course, any
       other parameter key that	triggers the "save" callback without a
       priority	override will still execute the	"save" callback	at its
       configured level.

   Request Callbacks
       Request callbacks come in two flavors: those that execute before	the
       parameter-triggered callbacks, and those	that execute after the
       parameter-triggered callbacks. Functional request callbacks may be
       specified via the "pre_callbacks" and "post_callbacks" parameters to
       "new()",	respectively:

	 my $cb_request	= Params::CallbackRequest->new
	   ( pre_callbacks  => [ \&translate, \&foobarate ],
	     post_callbacks => [ \&escape, \&negate ] );

       Object-oriented request callbacks may be	declared via the "PreCallback"
       and "PostCallback" method attributes, like so:

	 sub translate : PreCallback { ... }
	 sub foobarate : PreCallback { ... }
	 sub escape : PostCallback { ... }
	 sub negate : PostCallback { ... }

       In these	examples, the "translate()" and	"foobarate()" subroutines or
       methods will execute (in	that order) before any parameter-triggered
       callbacks are executed (none will be in these examples, since none are

       Conversely, the "escape()" and "negate()" subroutines or	methods	will
       be executed (in that order) after all parameter-triggered callbacks
       have been executed. And regardless of what parameter-triggered
       callbacks may be	triggered, the request callbacks will always be
       executed	for every request (unless an exception is thrown by an earlier

       Although	they may be used for different purposes, the "pre_callbacks"
       and "post_callbacks" functional callback	code references	expect the
       same argument as	parameter-triggered functional callbacks: a
       Params::Callback	object:

	 sub foo {
	     my	$cb = shift;
	     # Do your business	here.

       Similarly, object-oriented request callback methods will	be passed an
       object of the class defined in the class	key portion of the callback
       trigger -- either an object of the class	in which the callback is
       defined,	or an object of	a subclass:

	 sub foo : PostCallback	{
	     my	$self =	shift;
	     # ...

       Of course, the attributes of the	Params::Callback or subclass object
       will be different than in parameter-triggered callbacks.	For example,
       the "priority", "pkg_key", and "cb_key" attributes will naturally be
       undefined. It will, however, be the same	instance of the	object passed
       to all other functional callbacks -- or to all other class callbacks
       with the	same class key -- in a single request.

       Like the	parameter-triggered callbacks, request callbacks run under the
       nose of a custom	exception handler, so if any of	them "die"s, an
       Params::Callback::Exception::Execution exception	will be	thrown.	Use
       the "exception_handler" parameter to "new()" if you don't like this.

   Parameters To The "new()" Constructor
       Params::CallbackRequest supports	a number of its	own parameters to the
       "new()" constructor (though none	of them, sadly,	trigger	callbacks).
       The parameters to "new()" are as	follows:

	   Parameter-triggered functional callbacks are	configured via the
	   "callbacks" parameter. This parameter is an array reference of hash
	   references, and each	hash reference specifies a single callback.
	   The supported keys in the callback specification hashes are:

	       Required. A string that,	when found in a	properly-formatted
	       parameter hash key, will	trigger	the execution of the callback.

	       Required. A reference to	the Perl subroutine that will be
	       executed	when the "cb_key" has been found in a parameter	hash
	       passed to "request()". Each code	reference should expect	a
	       single argument:	a Params::Callback object. The same instance
	       of a Params::Callback object will be used for all functional
	       callbacks in a single call to "request()".

	       Optional. A key to uniquely identify the	package	in which the
	       callback	subroutine is found. This parameter is useful in
	       systems with many callbacks, where developers may wish to use
	       the same	"cb_key" for different subroutines in different
	       packages. The default package key may be	set via	the
	       "default_pkg_key" parameter to "new()".

	       Optional. Indicates the level of	priority of a callback.	Some
	       callbacks are more important than others, and should be
	       executed	before the others.  Params::CallbackRequest supports
	       priority	levels ranging from "0"	(highest priority) to "9"
	       (lowest priority). The default priority for functional
	       callbacks may be	set via	the "default_priority" parameter.

	   This	parameter accepts an array reference of	code references	that
	   should be executed for every	call to	"request()" before any
	   parameter-triggered callbacks. They will be executed	in the order
	   in which they're listed in the array	reference. Each	code reference
	   should expect a Params::Callback object as its sole argument. The
	   same	instance of a Params::Callback object will be used for all
	   functional callbacks	in a single call to "request()". Use pre-
	   parameter-triggered request callbacks when you want to do something
	   with	the parameters submitted for every call	to "request()",	such
	   as convert character	sets.

	   This	parameter accepts an array reference of	code references	that
	   should be executed for every	call to	"request()" after all
	   parameter-triggered callbacks have been called. They	will be
	   executed in the order in which they're listed in the	array
	   reference. Each code	reference should expect	a Params::Callback
	   object as its sole argument.	The same instance of a
	   Params::Callback object will	be used	for all	functional callbacks
	   in a	single call to "request()". Use	post-parameter-triggered
	   request callbacks when you want to do something with	the parameters
	   submitted for every call to "request()", such as encode or escape
	   their values	for presentation.

	   An array reference listing the class	keys of	all of the
	   Params::Callback subclasses containing callback methods that	you
	   want	included in your Params::CallbackRequest object.
	   Alternatively, the "cb_classes" parameter may simply	be the word
	   "ALL", in which case	all Params::Callback subclasses	will have
	   their callback methods registered with your Params::CallbackRequest
	   object. See the Params::Callback documentation for details on
	   creating callback classes and methods.

	   Note: In a mod_perl environment, be sure to "use
	   Params::CallbackRequest" only after you've "use"d all of the
	   Params::Callback subclasses you need	or else	you won't be able to
	   use their callback methods.

	   The priority	level at which functional callbacks will be executed.
	   Does	not apply to object-oriented callbacks.	This value will	be
	   used	in each	hash reference passed via the "callbacks" parameter to
	   "new()" that	lacks a	"priority" key.	You may	specify	a default
	   priority level within the range of "0" (highest priority) to	"9"
	   (lowest priority). If not specified,	it defaults to "5".

	   The default package key for functional callbacks. Does not apply to
	   object-oriented callbacks. This value that will be used in each
	   hash	reference passed via the "callbacks" parameter to "new()" that
	   lacks a "pkg_key" key. It can be any	string that evaluates to a
	   true	value, and defaults to "DEFAULT" if not	specified.

	   By default, Params::CallbackRequest will execute all	callbacks
	   triggered by	parameter hash keys. However, in many situations it
	   may be desirable to skip any	callbacks that have no value for the
	   callback field. One can do this by simply checking "$cbh->value" in
	   the callback, but if	you need to disable the	execution of all
	   parameter-triggered callbacks when the callback parameter value is
	   undefined or	the null string	(''), pass the "ignore_null" parameter
	   with	a true value. It is set	to a false value by default.

	   By default, Params::CallbackRequest will clear out the contents of
	   the hash accessed via the "notes()" method just before returning
	   from	a call to "request()". There may be some circumstances when
	   it's	desirable to allow the notes hash to persist beyond the
	   duration of a a call	to "request()".	For example, a templating
	   architecture	may wish to keep the notes around for the duration of
	   the execution of a template request.	In such	cases, pass a true
	   value to the	"leave_notes" parameter, and use the "clear_notes()"
	   method to manually clear out	the notes hash at the appropriate

	   Params::CallbackRequest installs a custom exception handler during
	   the execution of callbacks. This custom exception handler will
	   simply rethrow any exception	objects	it comes across, but will
	   throw a Params::Callback::Exception::Execution exception object if
	   it is passed	only a string value (such as is	passed by "die

	   But if you find that	you're throwing	your own exceptions in your
	   callbacks, and want to handle them differently, pass	the
	   "exception_handler" parameter a code	reference to do	what you need.

   Instance Methods
       Params::CallbackRequest of course has several instance methods. I cover
       the most	important, first.



	 # If you're in	a mod_perl environment,	pass in	an Apache request object
	 # to be passed	to the Callback	classes.
	 $cb_request->request(\%params,	apache_req => $r);

	 # Or pass in argument to be passed to callback	class constructors.
	 $cb_request->request(\%params,	@args);

       Executes	the callbacks specified	when the Params::CallbackRequest
       object was created. It takes a single required argument,	a hash
       reference of parameters.	Any subsequent arguments are passed to the
       constructor for each callback class for which callbacks will be
       executed. By default, the only extra parameter supported	by the
       Params::Callback	base class is an Apache	request	object,	which can be
       passed via the "apache_req" parameter. Returns the
       Params::CallbackRequest object on success, or the code passed to
       Params::Callback's "abort()" method if callback execution was aborted.

       A single	call to	"request()" is referred	to as a	"callback request"
       (naturally!). First, all	pre-request callbacks are executed. Then, any
       parameter-triggered callbacks triggered by the keys in the parameter
       hash reference passed as	the sole argument are executed.	And finally,
       all post-request	callbacks are executed.	"request()" returns the
       Params::CallbackRequest object on successful completion of the request.

       Any callback that calls "abort()" on its	Params::Callback object	will
       prevent any other callbacks scheduled by	the request to run subsequent
       to its execution	from being executed (including post-request
       callbacks). Furthermore,	any callback that "die"s or throws an
       exception will of course	also prevent any subsequent callbacks from
       executing, and in addition must also be caught by the caller or the
       whole process will terminate:

	 eval {	$cb_request->request(\%params) };
	 if (my	$err = $@) {
	     # Handle exception.


	 $cb_request->notes($key => $value);
	 my $val = $cb_request->notes($key);
	 my $notes = $cb_request->notes;

       The "notes()" method provides a place to	store application data,	giving
       developers a way	to share data among multiple callbacks over the	course
       of a call to "request()". Any data stored here persists for the
       duration	of the request unless the "leave_notes"	parameter to "new()"
       has been	passed a true value. In	such cases, use	"clear_notes()"	to
       manually	clear the notes.

       Conceptually, "notes()" contains	a hash of key-value pairs.
       "notes($key, $value)" stores a new entry	in this	hash. "notes($key)"
       returns a previously stored value. "notes()" without any	arguments
       returns a reference to the entire hash of key-value pairs.

       "notes()" is similar to the mod_perl method "$r->pnotes()". The main
       differences are that this "notes()" can be used in a non-mod_perl
       environment, and	that its lifetime is tied to the lifetime of the call
       to "request()" unless the "leave_notes" parameter is true.

       For the sake of convenience, a shortcut to "notes()" is provide to
       callback	code via the "notes()" method in Params::Callback.



       Use this	method to clear	out the	notes hash. Most useful	when the
       "leave_notes" parameter to "new()" has been set to at true value	and
       you need	to manage the clearing of notes	yourself. This method is
       specifically designed for a templating environment, where it may	be
       advantageous for	the templating architecture to allow the notes to
       persist beyond the duration of a	call to	"request()", e.g., to keep
       them for	the duration of	a call to the templating architecture itself.
       See MasonX::Interp::WithCallbacks for an	example	of this	strategy.

   Accessor Methods
       The properties "default_priority" and "default_pkg_key" have standard
       read-only accessor methods of the same name. For	example:

	 my $cb_request	= Params::CallbackRequest->new;
	 my $default_priority =	$cb_request->default_priority;
	 my $default_pkg_key = $cb_request->default_pkg_key;

       Garth Webb implemented the original callbacks in	Bricolage, based on an
       idea he borrowed	from Paul Lindner's work with Apache::ASP. My thanks
       to them both for	planting this great idea! This implementation is
       however completely independent of previous implementations.

       Params::Callback	objects	get passed as the sole argument	to all
       functional callbacks, and offer access to data relevant to the
       callback. Params::Callback also defines the object-oriented callback
       interface, making its documentation a must-read for anyone who wishes
       to create callback classes and methods.

       MasonX::Interp::WithCallbacks uses this module to provide a callback
       architecture for	HTML::Mason.

       This module is stored in	an open	GitHub repository
       <>. Feel	free to	fork
       and contribute!

       Please file bug reports via GitHub Issues
       <> or by sending
       mail to <mailto:bug-params->.

       David E.	Wheeler	<>

       Copyright 2003-2011 David E. Wheeler. Some Rights Reserved.

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

perl v5.32.0			  2020-08-09	    Params::CallbackRequest(3)


Want to link to this manual page? Use this URL:

home | help