This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: add-hook!


(nobody) writes:

> 1) don't use anonymous procs for hooks -- give them names and don't
> lose them

I've got some hooks in one of the guile applications I work on, and
I've decided that this is by far the best solution.  It's the only way
I've been able to think of that allows for painless run time
redefinition of hooks.

I use a macro to make things easier.  Eventually, I wanted to have
some facility to ensure the order in which the hooks run, so I added
an optional priority.  I've included the code for demonstration
purposes.

-russ

;;; This is a list of function-names/functions that get called at ui
;;; initialization time.  It is convenient to have this facility,
;;; because this source file does not have access to every other bit
;;; of the system that may need to initialize ui's in some way.  So we
;;; let those other parts of the system do the initialization with a
;;; hook.  There is also a crude way of specifying the order in which
;;; these functions are run, by using the optional priority argument.
(define *default-priority* 5)
(define *ui-init-hook-list* '())

(define-record hook
  (name
   function
   priority))

(define (add-ui-initialize-hook-helper name function priority)
  "Create a new hook using NAME FUNCTION and PRIORITY, and install it
into '*ui-init-hook-list*' in the correct position given PRIORITY,
after first removing any other hooks in '*ui-init-hook-list*' that
share NAME.  PRIORITY determines the correct position; hook functions
are sorted in increasing order of PRIORITY."
  (let ((priority (if (null? priority) 
		      *default-priority* 
		      (car priority))))
    (set! *ui-init-hook-list*
	  (sort (cons (make-hook name function priority)
		      (remove-if (lambda (hook) (eq? (hook->name hook) name))
				 *ui-init-hook-list*))
		(lambda (h1 h2)
		  (< (hook->priority h1)
		     (hook->priority h2))))))
  #t)

;;; A macro that calls the helper function.  This funny business with
;;; saving the function's name in addition to it's definition exists
;;; so that one can interactively redefine hook functions without the
;;; need for restarting the program.
(defmacro add-ui-initialize-hook! (function-name . maybe-priority)
  `(add-ui-initialize-hook-helper 
    (quote ,function-name)
    ,function-name
    (quote ,maybe-priority)))



--
A computer lets you make more mistakes faster than any invention in
human history with the possible exceptions of handguns and tequila.
             -- Mitch Ratliffe, Technology Review, April, 1992