| [ < ] | [ > ] | [ << ] | [Plus haut] | [ >> ] | [Top] | [Table des matières] | [Index] | [ ? ] |
catch and throw One way to use catch and throw is to exit from a doubly nested
loop. (In most languages, this would be done with a “go to.”) Here we
compute (foo i j) for i and j varying from 0
to 9:
(defun search-foo ()
(catch 'loop
(let ((i 0))
(while (< i 10)
(let ((j 0))
(while (< j 10)
(if (foo i j)
(throw 'loop (list i j)))
(setq j (1+ j))))
(setq i (1+ i))))))
|
If foo ever returns non-nil, we stop immediately and return a
list of i and j. If foo always returns nil, the
catch returns normally, and the value is nil, since that is
the result of the while.
Here are two tricky examples, slightly different, showing two return points
at once. First, two return points with the same tag, hack:
(defun catch2 (tag)
(catch tag
(throw 'hack 'yes)))
⇒ catch2
(catch 'hack
(print (catch2 'hack))
'no)
-| yes
⇒ no
|
Since both return points have tags that match the throw, it goes to
the inner one, the one established in catch2. Therefore,
catch2 returns normally with value yes, and this value is
printed. Finally the second body form in the outer catch, which is
'no, is evaluated and returned from the outer catch.
Now let's change the argument given to catch2:
(catch 'hack (print (catch2 'quux)) 'no) ⇒ yes |
We still have two return points, but this time only the outer one has the
tag hack; the inner one has the tag quux instead. Therefore,
throw makes the outer catch return the value yes. The
function print is never called, and the body-form 'no is never
evaluated.
Ce document a été généré par Eric Reinbold le 13 Octobre 2007 en utilisant texi2html 1.78.