377 |
@section Hooks |
@section Hooks |
378 |
@tpindex Hooks |
@tpindex Hooks |
379 |
|
|
380 |
@c FIXME::martin: Review me! |
A hook is a list of procedures to be called at well defined points in |
381 |
|
time. Typically, an application provides a hook @var{h} and promises |
382 |
A hook is basically a list of procedures to be called at well defined |
its users that it will call all of the procedures in @var{h} at a |
383 |
points in time. Hooks are used internally for several debugging |
defined point in the application's processing. By adding its own |
384 |
facilities, but they can be used in user code, too. |
procedure to @var{h}, an application user can tap into or even influence |
385 |
|
the progress of the application. |
386 |
Hooks are created with @code{make-hook}, then procedures can be added to |
|
387 |
a hook with @code{add-hook!} or removed with @code{remove-hook!} or |
Guile itself provides several such hooks for debugging and customization |
388 |
@code{reset-hook!}. The procedures stored in a hook can be invoked with |
purposes: these are listed in a subsection below. |
389 |
@code{run-hook}. |
|
390 |
|
When an application first creates a hook, it needs to know how many |
391 |
|
arguments will be passed to the hook's procedures when the hook is run. |
392 |
|
The chosen number of arguments (which may be none) is declared when the |
393 |
|
hook is created, and all the procedures that are added to that hook must |
394 |
|
be capable of accepting that number of arguments. |
395 |
|
|
396 |
|
A hook is created using @code{make-hook}. A procedure can be added to |
397 |
|
or removed from a hook using @code{add-hook!} or @code{remove-hook!}, |
398 |
|
and all of a hook's procedures can be removed together using |
399 |
|
@code{reset-hook!}. When an application wants to run a hook, it does so |
400 |
|
using @code{run-hook}. |
401 |
|
|
402 |
@menu |
@menu |
403 |
* Hook Examples:: Hook usage by example. |
* Hook Example:: Hook usage by example. |
404 |
* Hook Reference:: Reference of all hook procedures. |
* Hook Reference:: Reference of all hook procedures. |
405 |
|
* C Hooks:: Hooks for use from C code. |
406 |
|
* Guile Hooks:: Hooks provided by Guile. |
407 |
@end menu |
@end menu |
408 |
|
|
409 |
@node Hook Examples |
|
410 |
@subsection Hook Examples |
@node Hook Example |
411 |
|
@subsection Hook Usage by Example |
412 |
|
|
413 |
Hook usage is shown by some examples in this section. First, we will |
Hook usage is shown by some examples in this section. First, we will |
414 |
define a hook of arity 2 --- that is, the procedures stored in the hook |
define a hook of arity 2 --- that is, the procedures stored in the hook |
423 |
Now we are ready to add some procedures to the newly created hook with |
Now we are ready to add some procedures to the newly created hook with |
424 |
@code{add-hook!}. In the following example, two procedures are added, |
@code{add-hook!}. In the following example, two procedures are added, |
425 |
which print different messages and do different things with their |
which print different messages and do different things with their |
426 |
arguments. When the procedures have been added, we can invoke them |
arguments. |
|
using @code{run-hook}. |
|
427 |
|
|
428 |
@lisp |
@lisp |
429 |
(add-hook! hook (lambda (x y) |
(add-hook! hook (lambda (x y) |
434 |
(display "Bar: ") |
(display "Bar: ") |
435 |
(display (* x y)) |
(display (* x y)) |
436 |
(newline))) |
(newline))) |
437 |
|
@end lisp |
438 |
|
|
439 |
|
Once the procedures have been added, we can invoke the hook using |
440 |
|
@code{run-hook}. |
441 |
|
|
442 |
|
@lisp |
443 |
(run-hook hook 3 4) |
(run-hook hook 3 4) |
444 |
@print{} Bar: 12 |
@print{} Bar: 12 |
445 |
@print{} Foo: 7 |
@print{} Foo: 7 |
446 |
@end lisp |
@end lisp |
447 |
|
|
448 |
Note that the procedures are called in reverse order than they were |
Note that the procedures are called in the reverse of the order with |
449 |
added. This can be changed by providing the optional third argument |
which they were added. This is because the default behaviour of |
450 |
on the second call to @code{add-hook!}. |
@code{add-hook!} is to add its procedure to the @emph{front} of the |
451 |
|
hook's procedure list. You can force @code{add-hook!} to add its |
452 |
|
procedure to the @emph{end} of the list instead by providing a third |
453 |
|
@code{#t} argument on the second call to @code{add-hook!}. |
454 |
|
|
455 |
@lisp |
@lisp |
456 |
(add-hook! hook (lambda (x y) |
(add-hook! hook (lambda (x y) |
461 |
(display "Bar: ") |
(display "Bar: ") |
462 |
(display (* x y)) |
(display (* x y)) |
463 |
(newline)) |
(newline)) |
464 |
#t) ; @r{<- Change here!} |
#t) ; @r{<- Change here!} |
465 |
|
|
466 |
(run-hook hook 3 4) |
(run-hook hook 3 4) |
467 |
@print{} Foo: 7 |
@print{} Foo: 7 |
468 |
@print{} Bar: 12 |
@print{} Bar: 12 |
469 |
@end lisp |
@end lisp |
470 |
|
|
471 |
|
|
472 |
@node Hook Reference |
@node Hook Reference |
473 |
@subsection Hook Reference |
@subsection Hook Reference |
474 |
|
|
475 |
When a hook is created with @code{make-hook}, you can supply the arity |
When you create a hook with @code{make-hook}, you must specify the arity |
476 |
of the procedures which can be added to the hook. The arity defaults to |
of the procedures which can be added to the hook. If the arity is not |
477 |
zero. All procedures of a hook must have the same arity, and when the |
given explicitly as an argument to @code{make-hook}, it defaults to |
478 |
procedures are invoked using @code{run-hook}, the number of arguments |
zero. All procedures of a given hook must have the same arity, and when |
479 |
must match the arity of the procedures. |
the procedures are invoked using @code{run-hook}, the number of |
480 |
|
arguments passed must match the arity specified at hook creation time. |
481 |
|
|
482 |
The order in which procedures are added to a hook matters. If the third |
The order in which procedures are added to a hook matters. If the third |
483 |
parameter to @var{add-hook!} is omitted or is equal to @code{#f}, the |
parameter to @code{add-hook!} is omitted or is equal to @code{#f}, the |
484 |
procedure is added in front of the procedures which might already be on |
procedure is added in front of the procedures which might already be on |
485 |
that hook, otherwise the procedure is added at the end. The procedures |
that hook, otherwise the procedure is added at the end. The procedures |
486 |
are always called from first to last when they are invoked via |
are always called from the front to the end of the list when they are |
487 |
@code{run-hook}. |
invoked via @code{run-hook}. |
488 |
|
|
489 |
When calling @code{hook->list}, the procedures in the resulting list are |
The ordering of the list of procedures returned by @code{hook->list} |
490 |
in the same order as they would have been called by @code{run-hook}. |
matches the order in which those procedures would be called if the hook |
491 |
|
was run using @code{run-hook}. |
492 |
|
|
493 |
@deffn {Scheme Procedure} make-hook [n_args] |
@deffn {Scheme Procedure} make-hook [n_args] |
494 |
@deffnx {C Function} scm_make_hook (n_args) |
@deffnx {C Function} scm_make_hook (n_args) |
528 |
value of this procedure is not specified. |
value of this procedure is not specified. |
529 |
@end deffn |
@end deffn |
530 |
|
|
531 |
|
@deffn {Scheme Procedure} hook->list hook |
532 |
|
@deffnx {C Function} scm_hook_to_list (hook) |
533 |
|
Convert the procedure list of @var{hook} to a list. |
534 |
|
@end deffn |
535 |
|
|
536 |
@deffn {Scheme Procedure} run-hook hook . args |
@deffn {Scheme Procedure} run-hook hook . args |
537 |
@deffnx {C Function} scm_run_hook (hook, args) |
@deffnx {C Function} scm_run_hook (hook, args) |
538 |
Apply all procedures from the hook @var{hook} to the arguments |
Apply all procedures from the hook @var{hook} to the arguments |
540 |
last. The return value of this procedure is not specified. |
last. The return value of this procedure is not specified. |
541 |
@end deffn |
@end deffn |
542 |
|
|
543 |
@deffn {Scheme Procedure} hook->list hook |
If, in C code, you are certain that you have a hook object and well |
544 |
@deffnx {C Function} scm_hook_to_list (hook) |
formed argument list for that hook, you can also use |
545 |
Convert the procedure list of @var{hook} to a list. |
@code{scm_c_run_hook}, which is identical to @code{scm_run_hook} but |
546 |
@end deffn |
does no type checking. |
547 |
|
|
548 |
|
@deftypefn {C Function} void scm_c_run_hook (SCM hook, SCM args) |
549 |
|
The same as @code{scm_run_hook} but without any type checking to confirm |
550 |
|
that @var{hook} is actually a hook object and that @var{args} is a |
551 |
|
well-formed list matching the arity of the hook. |
552 |
|
@end deftypefn |
553 |
|
|
554 |
|
|
555 |
|
@node C Hooks |
556 |
|
@subsection Hooks For C Code. |
557 |
|
|
558 |
|
The hooks already described are intended to be populated by Scheme-level |
559 |
|
procedures. In addition to this, the Guile library provides an |
560 |
|
independent set of interfaces for the creation and manipulation of hooks |
561 |
|
that are designed to be populated by functions implemented in C. |
562 |
|
|
563 |
|
The original motivation here was to provide a kind of hook that could |
564 |
|
safely be invoked at various points during garbage collection. |
565 |
|
Scheme-level hooks are unsuitable for this purpose as running them could |
566 |
|
itself require memory allocation, which would then invoke garbage |
567 |
|
collection recursively @dots{} However, it is also the case that these |
568 |
|
hooks are easier to work with than the Scheme-level ones if you only |
569 |
|
want to register C functions with them. So if that is mainly what your |
570 |
|
code needs to do, you may prefer to use this interface. |
571 |
|
|
572 |
|
To create a C hook, you should allocate storage for a structure of type |
573 |
|
@code{scm_t_c_hook} and then initialize it using @code{scm_c_hook_init}. |
574 |
|
|
575 |
|
@deftp {C Type} scm_t_c_hook |
576 |
|
Data type for a C hook. The internals of this type should be treated as |
577 |
|
opaque. |
578 |
|
@end deftp |
579 |
|
|
580 |
|
@deftp {C Enum} scm_t_c_hook_type |
581 |
|
Enumeration of possible hook types, which are: |
582 |
|
|
583 |
|
@table @code |
584 |
|
@item SCM_C_HOOK_NORMAL |
585 |
|
@vindex SCM_C_HOOK_NORMAL |
586 |
|
Type of hook for which all the registered functions will always be called. |
587 |
|
@item SCM_C_HOOK_OR |
588 |
|
@vindex SCM_C_HOOK_OR |
589 |
|
Type of hook for which the sequence of registered functions will be |
590 |
|
called only until one of them returns C true (a non-NULL pointer). |
591 |
|
@item SCM_C_HOOK_AND |
592 |
|
@vindex SCM_C_HOOK_AND |
593 |
|
Type of hook for which the sequence of registered functions will be |
594 |
|
called only until one of them returns C false (a NULL pointer). |
595 |
|
@end table |
596 |
|
@end deftp |
597 |
|
|
598 |
|
@deftypefn {C Function} void scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hook_type type) |
599 |
|
Initialize the C hook at memory pointed to by @var{hook}. @var{type} |
600 |
|
should be one of the values of the @code{scm_t_c_hook_type} enumeration, |
601 |
|
and controls how the hook functions will be called. @var{hook_data} is |
602 |
|
a closure parameter that will be passed to all registered hook functions |
603 |
|
when they are called. |
604 |
|
@end deftypefn |
605 |
|
|
606 |
|
To add or remove a C function from a C hook, use @code{scm_c_hook_add} |
607 |
|
or @code{scm_c_hook_remove}. A hook function must expect three |
608 |
|
@code{void *} parameters which are, respectively: |
609 |
|
|
610 |
|
@table @var |
611 |
|
@item hook_data |
612 |
|
The hook closure data that was specified at the time the hook was |
613 |
|
initialized by @code{scm_c_hook_init}. |
614 |
|
|
615 |
|
@item func_data |
616 |
|
The function closure data that was specified at the time that that |
617 |
|
function was registered with the hook by @code{scm_c_hook_add}. |
618 |
|
|
619 |
|
@item data |
620 |
|
The call closure data specified by the @code{scm_c_hook_run} call that |
621 |
|
runs the hook. |
622 |
|
@end table |
623 |
|
|
624 |
|
@deftp {C Type} scm_t_c_hook_function |
625 |
|
Function type for a C hook function: takes three @code{void *} |
626 |
|
parameters and returns a @code{void *} result. |
627 |
|
@end deftp |
628 |
|
|
629 |
|
@deftypefn {C Function} void scm_c_hook_add (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data, int appendp) |
630 |
|
Add function @var{func}, with function closure data @var{func_data}, to |
631 |
|
the C hook @var{hook}. The new function is appended to the hook's list |
632 |
|
of functions if @var{appendp} is non-zero, otherwise prepended. |
633 |
|
@end deftypefn |
634 |
|
|
635 |
|
@deftypefn {C Function} void scm_c_hook_remove (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data) |
636 |
|
Remove function @var{func}, with function closure data @var{func_data}, |
637 |
|
from the C hook @var{hook}. @code{scm_c_hook_remove} checks both |
638 |
|
@var{func} and @var{func_data} so as to allow for the same @var{func} |
639 |
|
being registered multiple times with different closure data. |
640 |
|
@end deftypefn |
641 |
|
|
642 |
|
Finally, to invoke a C hook, call the @code{scm_c_hook_run} function |
643 |
|
specifying the hook and the call closure data for this run: |
644 |
|
|
645 |
|
@deftypefn {C Function} void * scm_c_hook_run (scm_t_c_hook *hook, void *data) |
646 |
|
Run the C hook @var{hook} will call closure data @var{data}. Subject to |
647 |
|
the variations for hook types @code{SCM_C_HOOK_OR} and |
648 |
|
@code{SCM_C_HOOK_AND}, @code{scm_c_hook_run} calls @var{hook}'s |
649 |
|
registered functions in turn, passing them the hook's closure data, each |
650 |
|
function's closure data, and the call closure data. |
651 |
|
|
652 |
|
@code{scm_c_hook_run}'s return value is the return value of the last |
653 |
|
function to be called. |
654 |
|
@end deftypefn |
655 |
|
|
656 |
|
|
657 |
|
@node Guile Hooks |
658 |
|
@subsection Hooks Provided by Guile |
659 |
|
|
660 |
|
@menu |
661 |
|
* GC Hooks:: Garbage collection hooks. |
662 |
|
* REPL Hooks:: Hooks into the Guile REPL. |
663 |
|
@end menu |
664 |
|
|
665 |
|
|
666 |
|
@node GC Hooks |
667 |
|
@subsubsection Hooks for Garbage Collection |
668 |
|
|
669 |
|
Whenever Guile performs a garbage collection, it calls the following |
670 |
|
hooks in the order shown. |
671 |
|
|
672 |
|
@defvr {C Hook} scm_before_gc_c_hook |
673 |
|
C hook called at the very start of a garbage collection, after setting |
674 |
|
@code{scm_gc_running_p} to 1, but before entering the GC critical |
675 |
|
section. |
676 |
|
|
677 |
|
If garbage collection is blocked because @code{scm_block_gc} is |
678 |
|
non-zero, GC exits early soon after calling this hook, and no further |
679 |
|
hooks will be called. |
680 |
|
@end defvr |
681 |
|
|
682 |
|
@defvr {C Hook} scm_before_mark_c_hook |
683 |
|
C hook called before beginning the mark phase of garbage collection, |
684 |
|
after the GC thread has entered a critical section. |
685 |
|
@end defvr |
686 |
|
|
687 |
|
@defvr {C Hook} scm_before_sweep_c_hook |
688 |
|
C hook called before beginning the sweep phase of garbage collection. |
689 |
|
This is the same as at the end of the mark phase, since nothing else |
690 |
|
happens between marking and sweeping. |
691 |
|
@end defvr |
692 |
|
|
693 |
|
@defvr {C Hook} scm_after_sweep_c_hook |
694 |
|
C hook called after the end of the sweep phase of garbage collection, |
695 |
|
but while the GC thread is still inside its critical section. |
696 |
|
@end defvr |
697 |
|
|
698 |
|
@defvr {C Hook} scm_after_gc_c_hook |
699 |
|
C hook called at the very end of a garbage collection, after the GC |
700 |
|
thread has left its critical section. |
701 |
|
@end defvr |
702 |
|
|
703 |
|
@defvr {Scheme Hook} after-gc-hook |
704 |
|
@vindex scm_after_gc_hook |
705 |
|
Scheme hook with arity 0. This hook is run asynchronously |
706 |
|
(@pxref{Asyncs}) soon after the GC has completed and any other events |
707 |
|
that were deferred during garbage collection have been processed. (Also |
708 |
|
accessible from C with the name @code{scm_after_gc_hook}.) |
709 |
|
@end defvr |
710 |
|
|
711 |
|
All the C hooks listed here have type @code{SCM_C_HOOK_NORMAL}, are |
712 |
|
initialized with hook closure data NULL, are are invoked by |
713 |
|
@code{scm_c_hook_run} with call closure data NULL. |
714 |
|
|
715 |
|
@cindex guardians, testing for GC'd objects |
716 |
|
The Scheme hook @code{after-gc-hook} is particularly useful in |
717 |
|
conjunction with guardians (@pxref{Guardians}). Typically, if you are |
718 |
|
using a guardian, you want to call the guardian after garbage collection |
719 |
|
to see if any of the objects added to the guardian have been collected. |
720 |
|
By adding a thunk that performs this call to @code{after-gc-hook}, you |
721 |
|
can ensure that your guardian is tested after every garbage collection |
722 |
|
cycle. |
723 |
|
|
724 |
|
|
725 |
|
@node REPL Hooks |
726 |
|
@subsubsection Hooks into the Guile REPL |
727 |
|
|
728 |
|
|
729 |
@c Local Variables: |
@c Local Variables: |