ClassCastException clojure.lang.Var$Unbound Help

1,540 views
Skip to first unread message

Travis Smith

unread,
Apr 30, 2012, 11:39:21 AM4/30/12
to clo...@googlegroups.com
What does 'java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to clojure.lang.IDeref' mean. I'm getting this a lot and I want to understand it better, make it easier for me to avoid this. Most of the time I just end up adjusting my def/defn's around until it works. This is hardly optimal. 

(this is all on clojure 1.3.0)

An example...

(ns app-admin.models.current-user
  (:require [noir.session :as session]
            [app-admin.models.users :as users]))

(def get-id
  (session/get :uid))

(defn set-user! [user] 
  (session/put! :uid {:_id user}))

Give me an exception for get-id

ClassCastException clojure.lang.Var$Unbound cannot be cast to clojure.lang.IDeref  clojure.core/deref (core.clj:2078)

So set-user! binds correctly, but get-id doesn't seem to...

=> (get-id)
llegalStateException Attempting to call unbound fn: #'app-admin.models.current-user/get-id  clojure.lang.Var$Unbound.throwArity (Var.java:43)

Then I check it...

=> (meta #'get-id)
{:ns #<Namespace app-admin.models.current-user>, :name get-id}


So it's there, the fn is bound; I'm not exactly sure what's going on and nor what I'm missing about how this works to help me avoid problems like this in future. Just guessing and tweaking has gotten me so far, but that's not sustainable. 

Thanks!

-Travis

Dave Ray

unread,
Apr 30, 2012, 9:30:47 PM4/30/12
to clo...@googlegroups.com
I think what you actually want is:

(defn get-id []
(session/get :uid))

in your code, you're trying to call #'session/get directly and bind it
to get-id. Of course, the problem with this is that #'session/get
expects to be called in the context of a request which is where your
Unbound var exception is coming from.

Hope this helps,

Dave
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

Stuart Campbell

unread,
Apr 30, 2012, 9:31:17 PM4/30/12
to clo...@googlegroups.com
Hi Travis,

(def get-id
  (session/get :uid))

(defn set-user! [user] 
  (session/put! :uid {:_id user}))

Only set-user! is a function here. The value of get-id is evaluated at compile-time.

I don't know about the implementation of noir.session/get, but the error message suggests that it uses some dynamic var that is unbound at compile-time. That makes sense since you couldn't reference a session without an associated request.

Changing get-id to something like:

(defn get-id []
  (session/get :uid))

will probably do what you expect.

=> (meta #'get-id)
{:ns #<Namespace app-admin.models.current-user>, :name get-id}


So it's there, the fn is bound [...]

Actually no, you're looking up the metadata on the var, not the value. Observe the following:

user> (def foo)
#'user/foo
user> foo
#<Unbound Unbound: #'user/foo>
user> (meta #'foo)
{:ns #<Namespace user>, :name foo, :line 1, :file "NO_SOURCE_FILE"}

See also http://clojure.org/vars

Regards,
Stuart

Travis Smith

unread,
Apr 30, 2012, 10:59:48 PM4/30/12
to clo...@googlegroups.com
Thank you for your responses. This was failing for me in the Noir server, so I assumed the same error meant the same thing in the REPL. Something was different though, changing it to (defn get-id ...) and a couple other minor tweaks and it's working. 
Reply all
Reply to author
Forward
0 new messages