NAME

Sub::Context - Perl extension to dispatch subroutines based on their calling context

SYNOPSIS

use Sub::Context sensitive => {
	void	=> \&whine,
	scalar	=> \&cry,
	list	=> \&weep,
};

DESCRIPTION

Sub::Context automagically dispatches subroutine calls based on their calling context. This can be handy for converting return values or for throwing warnings or even fatal errors. For example, you can prohibit a function from being called in void context. Instead of playing around with wantarray() on your own, it's handled automatically.

EXPORT

None by default. Simply use the module and its custom import() function will handle things nicely for you.

IMPORTING

By convention, Sub::Context takes a list of arguments in pairs. The first item is always considered to be the name of a subroutine. The second item in the list is a reference to a hash of options for that subroutine. For example, to create a new sub, in the calling package, named penguinize, with three existing subroutines for each of the three types of context (void, list, and scalar), write:

use Sub::Context
	penguinize => {
		void	=> \&void_penguinize,
		list	=> \&list_penguinize,
		scalar	=> \&scalar_penguinize,
	};

You can provide your own subroutine references, of course:

use Sub::Context
	daemonize => {
		list => sub { paint_red( penguinize() ) },
	};

If you are creating a new subroutine and do not provide a subroutine reference for a context type, Sub::Context will helpfully croak() when you call the sub with the unsupported context. You can also provide a scalar instead of a subref, which will be appended to the error message:

use Sub::Context 
	daemonize => {
		list => sub { paint_red( penguinize(@_) ) },
		void => 'daemons get snippy in void context',
	};

You're not limited to creating new subs. You can wrap existing subs, as well. In this release, they must be in the calling package, but this may be fixed in a future version. Note that in this case, if you do not provide a new behavior for a context type, the old behavior will be preserved. For example, if you have an existing sub that returns a string of words, you can say:

use Sub::Context
	get_sentence => {
		list => sub { split(' ', get_sentence(@_) },
		void => 'results too good to throw away',
	};

Called in scalar context, get_sentence() will behave like it always had. In list context, it will return a list of words (for whatever definition of 'words' the regex provides). In void context, it will croak with the provided error message.

TODO

Add optional support for Want (very soon)
Wrap subs in other packages
Allow unwrapping of wrapped subs (localized?)
World domination?

HISTORY

0.02

Validate context types as suggested by Ben Tilly.

0.01

Original version; created by h2xs 1.21 with options

  -C
	-A
	-X
	-n
	Sub::Context

AUTHOR

chromatic, <chromatic@wgz.org>

Other suggestions helpfully provided by thpfft, RhetTbull, and TheDamian on Perlmonks.org.

COPYRIGHT

Copyright 2001 by chromatic.

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

See http://www.perl.com/perl/misc/Artistic.html

SEE ALSO

perl, wantarray, Class::Multimethods.