summaryrefslogtreecommitdiff
path: root/pod
diff options
context:
space:
mode:
authorRobin Houston <robin@cpan.org>2005-10-29 22:33:07 +0100
committerH.Merijn Brand <h.m.brand@xs4all.nl>2005-11-02 12:49:54 +0000
commit9850bf21fc4ed69d8ddb0293df59411f891c62df (patch)
tree047a29a8cd2d04148aa15000e1307651d86afe8a /pod
parentbda6ed216cf53718fff278193bffd2c4078fb377 (diff)
downloadperl-9850bf21fc4ed69d8ddb0293df59411f891c62df.tar.gz
sort/multicall patch
Message-ID: <20051029203307.GA8869@rpc142.cs.man.ac.uk> p4raw-id: //depot/perl@25953
Diffstat (limited to 'pod')
-rw-r--r--pod/perlcall.pod45
-rw-r--r--pod/perldiag.pod12
2 files changed, 50 insertions, 7 deletions
diff --git a/pod/perlcall.pod b/pod/perlcall.pod
index dd520afcaa..fb5ea37f0f 100644
--- a/pod/perlcall.pod
+++ b/pod/perlcall.pod
@@ -1942,6 +1942,51 @@ will be the return value as well (read more about C<eval_pv> in
L<perlapi/eval_pv>). Once this code reference is in hand, it
can be mixed in with all the previous examples we've shown.
+=head1 LIGHTWEIGHT CALLBACKS
+
+Sometimes you need to invoke the same subroutine repeatedly.
+This usually happens with a function that acts on a list of
+values, such as Perl's built-in sort(). You can pass a
+comparison function to sort(), which will then be invoked
+for every pair of values that needs to be compared. The first()
+and reduce() functions from L<List::Util> follow a similar
+pattern.
+
+In this case it is possible to speed up the routine (often
+quite substantially) by using the lightweight callback API.
+The idea is that the calling context only needs to be
+created and destroyed once, and the sub can be called
+arbitrarily many times in between.
+
+It is usual to pass parameters using global variables -- typically
+$_ for one parameter, or $a and $b for two parameters -- rather
+than via @_. (It is possible to use the @_ mechanism if you know
+what you're doing, though there is as yet no supported API for
+it. It's also inherently slower.)
+
+The pattern of macro calls is like this:
+
+ dMULTICALL; /* Declare variables (including 'CV* cv') */
+ I32 gimme = G_SCALAR; /* context of the call: G_SCALAR,
+ * G_LIST, or G_VOID */
+
+ /* Here you must arrange for 'cv' to be set to the CV of
+ * the sub you want to call. */
+
+ PUSH_MULTICALL; /* Set up the calling context */
+
+ /* loop */ {
+ /* set the value(s) af your parameter variables */
+ MULTICALL; /* Make the actual call */
+ } /* end of loop */
+
+ POP_MULTICALL; /* Tear down the calling context */
+
+For some concrete examples, see the implementation of the
+first() and reduce() functions of List::Util 1.18. There you
+will also find a header file that emulates the multicall API
+on older versions of perl.
+
=head1 SEE ALSO
L<perlxs>, L<perlguts>, L<perlembed>
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 3c16b0d2b6..930a6cbdcc 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -761,6 +761,11 @@ a block, except that it isn't a proper block. This usually occurs if
you tried to jump out of a sort() block or subroutine, which is a no-no.
See L<perlfunc/goto>.
+=item Can't goto subroutine from a sort sub (or similar callback)
+(F) The "goto subroutine" call can't be used to jump out of the
+comparison sub for a sort(), or from a similar callback (such
+as the reduce() function in List::Util).
+
=item Can't goto subroutine from an eval-%s
(F) The "goto subroutine" call can't be used to jump out of an eval
@@ -954,13 +959,6 @@ missing. You need to figure out where your CRTL misplaced its environ
or define F<PERL_ENV_TABLES> (see L<perlvms>) so that environ is not
searched.
-=item Can't redefine active sort subroutine %s
-
-(F) Perl optimizes the internal handling of sort subroutines and keeps
-pointers into them. You tried to redefine one such sort subroutine when
-it was currently active, which is not allowed. If you really want to do
-this, you should write C<sort { &func } @x> instead of C<sort func @x>.
-
=item Can't "redo" outside a loop block
(F) A "redo" statement was executed to restart the current block, but