Search code examples
clojure

Why does `dir` not work with current namespace gotten from "current namespace var" - `*ns*`


Or, in other words, why does this not work:

user=> (dir (ns-name *ns*))
Execution error (ClassCastException) at user/eval2010 (REPL:1).
class clojure.lang.PersistentList cannot be cast to class clojure.lang.Symbol (clojure.lang.PersistentList and clojure.lang.Symbol are in unnamed module of loader 'bootstrap')

Solution

  • dir is a macro that expects an unquoted symbol as its argument. It should be used like:

    
    user=> (clojure.repl/dir clojure.string)
    blank?
    capitalize
    escape
    join
    lower-case
    replace
    ...
    

    When you call it like so:

    (ns demo.core
      (:require [clojure.repl :as repl]))
    
    (println (repl/dir (ns-name *ns*)))
    

    you are not passing an unquoted symbol (eg clojure.string), but rather a list with the symbol ns-name as its first element.

    As the namespace for clojure.repl/dir implies, this command is intended to by typed into a REPL by hand, not used programatically.


    If you do want to get information programatically, you probably want something more like one of these:

    (ns-publics 'tst.demo.core)
    (ns-publics (ns-name *ns*))
    

    either of which works.

    Be sure to peruse the Clojure CheatSheet and this list of documentation.