[Bese-devel] problem with actions

Drew Crampsie drewc at tech.coop
Tue Aug 2 22:17:04 UTC 2005


Carlos Ungil wrote:
> Hello,

> The test-list component (/test/index.ucw) shows a list of ten items 
> 0..9, and clicking on one of them won't show that number, as I would 
> like, but all of them display the number 10. I think this is because 10 
> is the value the of i variable after the loop, and somehow this is the 
> only value used by the system.

> (defmethod render-on ((res response) (app test-list))
>   (<:ul (loop for i from 0 below 10
>           do (<:li (<ucw:a :action (display-number app i)
>                    (<:as-html i))))))

This is because your implementation is free to re-use the binding of i
within the loop, and the <ucw:a is creating a closure over that binding.
  consider the following code :

CL> (defparameter *closures*
      (loop for i from 0 below 10 collect (lambda () i)))
*CLOSURES*
CL> (loop for c in *closures* collect (funcall c))
(10 10 10 10 10 10 10 10 10 10)
CL> (defparameter *closures*
      (loop for i from 0 below 10 collect (let ((i i))
                                           (lambda () i))))
*CLOSURES*
CL> (loop for c in *closures* collect (funcall c))
(0 1 2 3 4 5 6 7 8 9)

This is a common CL gotcha. All you need to do is change your loop to
look like this :

(loop for i from 0 below 10
          do (let ((i i))
              (<:li (<ucw:a :action (display-number app i)
                   (<:as-html i)))))))

drewc





More information about the bese-devel mailing list