[racket] Problem passing a reference

From: Ryan Culpepper (ryan at cs.utah.edu)
Date: Mon Sep 17 14:47:28 EDT 2012

On 09/17/2012 02:32 PM, Kieron Hardy wrote:
> Hi all,
>
> In the following fragment, I'm trying to create a new event, queue a
> callback to some handler to process that event, and then clear the event.
>
>      (define/private (create-message)
>        ...
>        (set! the-event (new some-event%))
>      ...
>        )
>
>      (define/private (queue-message receiver event)
>        ...
>            (when can-queue-message?
>              (queue-callback
>                (lambda () (send the-handler handle-event the-event)))
>                #t)
>        ...
>        (set! the-event #f)
>        ...
>        )
>
> However the event value that the handler actually sees is #f, i.e. the
> result after the event is cleared, and not as I want a reference to the
> event to process, i.e. the object resulting from the call to new.
>
> What is the best way to get to the handler, a reference to the event it
> needs to process?

Is there actually a reason to use 'set!'? Also, it's suspicious that 
your 'queue-message' method takes an 'event' argument but then refers to 
the 'the-event' field.

Here's what I would expect:

(define/private (some-method)
   ....
   (let ([the-event (new some-event%)])
     ....
     (queue-message receiver the-event)
     ....))

(define/private (queue-message receiver event)
   ....
   (when can-queue-message?
     (queue-callback
      (lambda () (send the-handler handle-event event))
      #t))
   ....)

If the method that creates the event doesn't directly call 
'queue-message', I would first try to have it return the event to the 
method that *does* call 'queue-message', possibly using multiple values 
if it returns other values too.

If none of that works and you really have to use 'set!', then the 
solution is to save the value to a local variable that doesn't get 
mutated and have the callback refer to that instead of the field:

(define/private (queue-message receiver ....)
   ....
   (let ([event-to-handle the-event])
     (set! the-event #f)
     (queue-callback
      (lambda () (send the-handler handle-event event-to-handle))
      #t))
   ....)

Ryan


Posted on the users mailing list.