8

When using clojure.string, I receive the following warnings

WARNING: replace already refers to: #'clojure.core/replace in namespace: tutorial.regexp, being replaced by: #'clojure.string/replace
WARNING: reverse already refers to: #'clojure.core/reverse in namespace: tutorial.regexp, being replaced by: #'clojure.string/reverse

my clojure script is:

(ns play-with-it
  (:use [clojure.string]))

Is there any way to fix those warnings?

4 Answers 4

15

Yes, switch to

(ns play-with-it
  (:require [clojure.string :as string]))

and then say e.g.

(string/replace ...)

to call clojure.string's replace function.

With :use, you bring in all Vars from clojure.string directly into your namespace, and since some of those have names clashing with Vars in clojure.core, you get the warning. Then you'd have to say clojure.core/replace to get at what's usually simply called replace.

The clash of names is by design; clojure.string is meant to be required with an alias like this. str and string are the most frequently chosen aliases.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. Was it possible to undestand that from the doc of use?" Like require, but also refers to each lib's namespace using clojure.core/refer" What do they mean by this sentence?
It means that use does exactly what require does and then on top of that it asks refer to create mappings in the current namespace for stuff exported by the namespace being used. (What I called bring[ing] all Vars from [the used namespace] directly into your namespace above.) Cf. (doc refer).
Joy of Clojure explains these pretty well too.
7

In addition to Michał's answer, you can exclude vars from clojure.core:

user=> (ns foo)
nil
foo=> (defn map [])
WARNING: map already refers to: #'clojure.core/map in namespace: foo, being replaced by: #'foo/map
#'foo/map
foo=> (ns bar
        (:refer-clojure :exclude [map]))
nil
bar=> (defn map [])
#'bar/map

Comments

4

In addition to Alex's answer you can also refer only the vars you want from a given namespace.

(ns foo.core
  (:use [clojure.string :only (replace-first)]))

This would not throw a warning since replace-first is not in clojure.core. However, you would still receive a warning if you did the following:

(ns foo.core
  (:use [clojure.string :only (replace)]))

In general it seems people are tending toward (ns foo.bar (:require [foo.bar :as baz])).

Comments

1

Since Clojure 1.4 you can refer the individual functions you need from a namespace using :require with a :refer:

(ns play-with-it
  (:require [clojure.string :refer [replace-first]]))

This is now recommended over :use.

Assuming you don't need the clojure.string/replace or clojure.string/reverse, that would also remove the warnings.

See this SO question and this JIRA issue for more details.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.