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] |
On Fri, Aug 21, 1998 at 09:07:47AM +0200, it occurred to Marius Vollmer to write: > Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes: > > > is it possible to get and change the environment of a given closure? > > In general, no. Of course, a simple set! changes the environment, too. Here's a little implementation of a special set! I had to make to get SIOD compatibility (for GIMP's script-fu scripts which extensively have the habit of set!ing undefined variables because SIOD allows it and the authors didn't know better..) ;; SIOD's set! is really screwed up. If the variable being set is ;; unbound, it is bound at the top level. Otherwise it is reset. So we ;; have to find out if a variable is bound in a _local_ environment.. thus ;; we create the syntax manually. Also, SIOD set! returns the new value. ;; There would be no prob otherwise, but all scripts use these "features".. (define-public set! ; we memoize the correct place for the variable.. (procedure->memoizing-macro (lambda (exp env) (define variable (cadr exp)) (define value (caddr exp)) (let loop ((e env)) (define frame (car e)) `(begin (,@(cond ((procedure? frame) ; here we create the top level binding `(',variable-set! ',(frame variable #t))) ((eq? (car frame) variable) `(',set-cdr! ',frame)) ((and (list? frame) (list-index (car frame) variable)) => (lambda (i) `(',set-car! ',(list-tail (cdr frame) i)))) (else (loop (cdr e)))) ,value) ,variable))))) Is there some better way to do this? There is no "local-defined?" procedure to my knowledge.. Lauri Alanko la@iki.fi