Re: Important question about garbage collection

From: Erick Gallesio <eg_at_kaolin.unice.fr>
Date: Mon, 12 Dec 1994 12:26:15 +0000

>
> I have a question about widget destruction and garbage collection, in
> particular w.r.t. to top level windows.
>
> Suppose I want to create a new top-level window within a lambda closure
> that's acting as a tk event handler callback.
> [text deleted]
> I guess my question is, in general, do you need to make sure that any
> widget is associated with the global environment in some way? Or can
> you create "local" widgets?

It depends wheter you use STk or STklos. What you must remember is that
when a Tk command is executed, it captures the environment in which it i
evaluated. Following code is incorrect, with to gc,

(define (g)
  (button (gensym ".widg") :text "foo" :command (address-of
                                                 (lambda ()
                                                   (display "Hi from g\n")))))

Try
   (pack (g))
   (gc)
   ;; and click the button will raise an error

A correct version would be
                                              
(define (h)
  (let ((callback (lambda ()(display "Hi from h\n"))))
    (button (gensym ".widg") :text "foo" :command (address-of callback))))

Here, when button is called, it captures an environment in wich callback
is known. Consequently this callbqck will not be garbaged.

With STklos, you obtain for free the second behaviour since the call to
the Tk command is done late (i.e. after the arguments are evaluated).
So following code is correct

(define (f)
  (make <Button> :text "foo" :command (address-of
                                       (lambda ()
                                         (display "Hi from f\n")))))


Following exemple creates a button which creates a new toplevel
for each click over it. I is close to the case you cite I think.
There is no GC problem with this code

(define (new-button)
  (make <Button>
        :text "Test"
        :command (address-of
                  (lambda ()
                    (let* ((t (make <Toplevel> :title "Top")))
                      (pack (make <Button>
                                  :text "foo"
                                  :parent t
                                  :command `(begin
                                              (gc)
                                              (destroy
                                               ,(address-of t))))))))))

Hope it helps



                -- Erick
Received on Mon Dec 12 1994 - 12:26:15 CET

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST