在slime REPL中使用clojure.contrib函数

14

我想在slime的REPL中使用clojure.contrib.trace命名空间中的函数。如何让slime自动加载它们?另一个相关问题是,如何将特定的命名空间添加到正在运行的REPL中?

在clojure.contrib API中,它描述了以下用法:

(ns my-namespace
  (:require clojure.contrib.trace))
但是将这段代码添加到我的项目中会导致文件无法加载,出现“无法解析符号”的错误,该错误会影响 trace 命名空间下的任何函数。
我使用 Leiningen 的 'lein swank' 命令来启动 ServerSocket,我的 project.clj 文件如下:
 (defproject test-project "0.1.0"
   :description "Connect 4 Agent written in Clojure"
   :dependencies [[org.clojure/clojure "1.2.0-master-SNAPSHOT"]
                  [org.clojure/clojure-contrib "1.2.0-SNAPSHOT"]]
   :dev-dependencies [[leiningen/lein-swank "1.2.0-SNAPSHOT"]
                      [swank-clojure "1.2.0"]])

所有看起来都是最新的,即'lein deps'不会产生任何更改。那么怎么回事?


1
你可能想把Michal的回答标记为正确答案。 - Bozhidar Batsov
1
Tyler,你应该将Michal的答案标记为此问题的被接受答案,因为它似乎解决了你的问题。这不仅是良好的行为规范,而且还可以提高你的声誉分数。只需单击问题分数旁边的复选标记即可。 - A. Levy
1个回答

18
  1. 如果你在代码中使用了:require,会出现“无法解析符号”的异常,这是因为:require只会使指定的命名空间本身可用,而不会将其中的变量引入。

    因此,如果你在ns表单中写入(:require foo.bar),那么你需要写foo.bar/quux来访问命名空间foo.bar中的变量quux。你也可以使用(:require [foo.bar :as fb])来缩短访问路径为fb/quux。另外一种可能性是使用(:use foo.bar),这样就可以在你的命名空间中使用来自foo.bar的所有变量。请注意,通常认为使用外部库的:use是不好的风格,但是在单个项目中使用可能还可以。

  2. 关于在REPL上自动让东西可用:

    ns表单中的:require:use:refer子句在clojure.core中分别对应着requireuserefer函数。同时也有对应:refer-clojure:import的宏。

    这意味着,为了让clojure.contrib.trace在REPL上可用,你可以像这样做:(require 'clojure.contrib.trace)或者(require '[clojure.contrib.trace :as trace])。请注意,由于require是一个函数,因此需要引用库规范。(userefer也需要引用的库规范;importrefer-clojure不需要引用任何内容。)

将适当的require调用放入~/.clojure/user.clj是在每次启动Clojure REPL时(包括使用SLIME时)都可以使用特定命名空间的最简单方法。请参阅John Lawrence Aspden的要求所有可能的命名空间博客文章,了解在user.clj中放置什么以拉入所有contrib的说明(尽管我不这样做,但我确实在那里有一个(use'clojure.contrib.repl-utils))。

非常感谢!在Emacs中进行调试现在变得更容易了。 - Limpoch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接