【问题标题】:How to break out of an infinite loop in emacs lisp ? (environment: emacs)如何打破 emacs lisp 中的无限循环? (环境:emacs)
【发布时间】:2011-07-19 06:25:01
【问题描述】:

我尝试使用 ctrl-c 然后 :a

但在这里不起作用。

我的代码是这样的:

(defun game-repl()
    (loop (print (eval (read)))))

然后我运行

(game-repl())
look()

【问题讨论】:

  • 游戏循环通常会有一个变量isDoneisNotDone,并且会基于它循环,例如(while is-not-done ... )。只需将is-not-done 设置为false,循环将在下一次迭代中中断。
  • 谢谢@Merlyn,但我的问题是如何打破这个循环回到我的 Lisp 编程环境,即 emacs。
  • 因此为什么是评论而不是答案 :) 但它会解决问题...只需在您的 REPL 中设置 is-not-done。但是是的,我可以看到您正在寻找编辑器命令,而不是可编程解决方案。
  • 谢谢梅林。我懂了。我搜索了一些来源。你说的对。我需要“告诉” lisp 什么时候出去。 ;)
  • (Game-repl ()) 应该发出错误信号,因为参数数量无效(期望没有,但得到一个)。 Look 很可能不是已定义的变量。 () 计算结果为 nil

标签: emacs lisp elisp


【解决方案1】:
(require 'cl)
(loop (setq x (read))
      (if (eq x 'exit)
        (return)
        (print (eval x))))

【讨论】:

    【解决方案2】:

    Emacs 模式通常仅在您连续按两次 Ctrl-C 时才向低级程序发送中断信号(即,您要查找的键序列是 C-c C-c)。对于SLIME 尤其如此。

    这是因为C-c 是一个prefix key,通常与其他键组合以访问一大堆特定于模式的功能。

    【讨论】:

      【解决方案3】:

      [参考http://www.psg.com/~dlamkins/sl/chapter05.html]

      大多数情况下,您编写 LOOP 表单时,您都希望有一条出路。幸运的是,内部任何地方的 RETURN 表单都会导致控件离开 LOOP;您指定的任何值都将成为 LOOP 表单的值:

       ? (loop
           (print "Here I am.")
           (return 17)
           (print "I never got here."))
       "Here I am."
       17
      

      RETURN 通常以条件形式使用,如下所示:

      ? (let ((n 0))
           (loop
             (when (> n 10) (return))
        (print n) (print (* n n))
        (incf n)))
      
      0 0
      1 1
      2 4
      3 9
      4 16
      5 25
      6 36
      7 49
      8 64
      9 81
      10 100
      NIL
      ?
      

      【讨论】:

        【解决方案4】:

        这个问题可以参考:

        1. 如何以编程方式跳出循环,否则该循环将无限或
        2. 如何手动停止已经在肆虐的无限循环。

        @fred-foo 令人满意地回答了第一个问题(这似乎是 OP 的实际问题)。 @matthias-benkard 解决了第二个问题,但他的答案不适用于 emacs lisp。

        手动停止正在运行的无限 emacs-lisp 循环的实际答案是 Ctrl+g(emacs-speak 中的 C-g)。

        emacs lisp manual 中有一个关于这个主题的文档页面。

        抱歉,我没有仅仅修改@matthias-benkard 的答案的声誉,而且这个问题在搜索引擎上排名很高......

        【讨论】:

          【解决方案5】:

          这个 Stack Exchange 答案是谷歌上“打破永无止境的循环粘液”的第一个热门话题

           C-c C-b
          

          缺少的是,不同的 lisp 以不同的方式处理此中断。我找到了这个答案,因为 GNU Clisp 只是不拦截 SLIME 的 C-c C-b。它也不像 SBCL 所做的那样拦截 C-c C-b 和 C-c C-c。

          【讨论】:

          • 我刚刚确认这是特定于 Windows 上的 Clisp。
          猜你喜欢
          • 2013-03-08
          • 1970-01-01
          • 2012-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多