How do we check if something is a link?

Now I use this:

(instance? clojure.lang.IDeref x)

... but I suspect there might be a better / more idiomatic way to do this.

+4
source share
1 answer

This is not true, you are checking to see if object x implements the IDeref interface, which simply means that you can dereference the object with the @ symbol. What you want is:

  (instance? clojure.lang.Ref x) 

EDIT:

(Correction of comments).

You can do what you suggested, but this has a drawback in classifying objects made by other users who extend IDeref to be considered a reference type. Also note that vars also behave like reference types, but do not use the IDeref interface.

There are two good options here. You can either write a function that uses the or operator:

  (def ref? [x] (or (instance? clojure.lang.Ref x) (instance? clojure.lang.Agent x) ...)) 

Or you can use protocols to define a new predicate. The advantage of this is its expandability.

  (defprotocol Ireference? (reference? [this])) (extend-type java.lang.Object Ireference? (reference? [this] false)) (extend-type nil Ireference (reference? [this] false)) (extend-type clojure.lang.Ref Ireference? (reference? [this] true)) (extend-type clojure.lang.Agent Ireference? (reference? [this] true)) ;;user=> (reference? nil) ;;false ;;user=> (reference? (ref 0)) ;;true 

In another example, see http://dosync.posterous.com/51626638

+4
source

All Articles