Code: Select all
(new Tree 'EVENTS-BEFORE)
(new Tree 'EVENTS-AFTER)
(define-macro (event-before target action)
(setf target (string target))
(unless (EVENTS-BEFORE target) (EVENTS-BEFORE target '(begin)) )
(extend (EVENTS-BEFORE target) (list action))
)
(define-macro (event-after target action)
(setf target (string target))
(unless (EVENTS-AFTER target) (EVENTS-AFTER target '(begin)) )
(extend (EVENTS-AFTER target) (list action))
)
(define-macro (with-events)
(let (_fun_ (string (args 0)) _res_ nil)
(eval (EVENTS-BEFORE _fun_))
(setf _res_ (eval $args))
(eval (EVENTS-AFTER _fun_))
_res_
)
)
Code: Select all
;; for now, same as (+ 4 5 6)
> (with-events + 4 5 6)
15
;; add a new "before" add event
> (event-before + (println "will add something : " $args))
;; then an "after" event
> (event-after + (println "done!"))
;; then, if i call "+" with events :
> (with-events + 4 5 6)
will add something : (+ 4 5 6)
done!
15
Any idea to make it better (something like a way for "before" events to change the args, for example ) ?
EDIT : some background about why i want do do this. For my web framework, the main cgi script is very simple, and should end with something like "(output)". This function will output the headers, and the content. Clean and simple.
But along the way i may have loaded a module to provide sessions, and another to access a database. So, i want these modules to be able to gracefully save the session and disconnect from the database at the end of the script, without having to invoque the coresponding function explicetly. The idea :
Code: Select all
;; in my framework :
(define (output)
(with-events output-headers)
(with-events output-content)
)
;; in a session handling extension
(event-before output-headers (SESSION:save))
;; in a text formater extension
(event-before output-content (TYPOGRAPHIST:reformat-all))
;; somwhere else
(event-after output-content (LOGGER:do-something))