问题
I want to use the functions in the clojure.contrib.trace namespace in slime at the REPL. How can I get slime to load them automatically? A related question, how can I add a specific namespace into a running repl?
On the clojure.contrib API it describes usage like this:
(ns my-namespace
(:require clojure.contrib.trace))
But adding this to my code results in the file being unable to load with an "Unable to resolve symbol" error for any function from the trace namespace.
I use leiningen 'lein swank' to start the ServerSocket and the project.clj file looks like this
(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"]])
Everything seems up to date, i.e. 'lein deps' doesn't produce any changes. So what's up?
回答1:
You're getting "Unable to resolve symbol" exceptions because
:require
doesn't pull in any Vars from the given namespace, it only makes the namespace itself available.Thus if you
(:require foo.bar)
in yourns
form, you have to writefoo.bar/quux
to access the Varquux
from the namespacefoo.bar
. You can also use(:require [foo.bar :as fb])
to be able to shorten that tofb/quux
. A final possiblity is to write(:use foo.bar)
instead; that makes all the Vars fromfoo.bar
available in your namespace. Note that it is generally considered bad style to:use
external libraries; it's probably ok within a single project, though.Re: automatically making stuff available at the REPL:
The
:require
,:use
and:refer
clauses ofns
forms have counterparts in therequire
,use
andrefer
functions inclojure.core
. There are also macros corresponding to:refer-clojure
and:import
.That means that in order to make
clojure.contrib.trace
available at the REPL you can do something like(require 'clojure.contrib.trace)
or(require '[clojure.contrib.trace :as trace])
. Note that becauserequire
is a function, you need to quote the library spec. (use
andrefer
also take quoted lib specs;import
andrefer-clojure
require no quoting.)The simplest way to have certain namespaces available every time you launch a Clojure REPL (including when you do it with SLIME) is to put the appropriate
require
calls in~/.clojure/user.clj
. See the Requiring all possible namespaces blog post by John Lawrence Aspden for a description of what you might put inuser.clj
to pull in all of contrib (something I don't do, personally, though I do have a(use 'clojure.contrib.repl-utils)
in there).
来源:https://stackoverflow.com/questions/2854618/using-clojure-contrib-functions-in-slime-repl