[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