proper way to override clojure.core functions without getting warning/error

Visto 805 veces
Saltar al primer mensaje no leído

AtKaaZ

no leída,
14 feb 2013, 13:04:5514/2/13
a clo...@googlegroups.com
Let's say I want to override clojure.core/sorted?

(ns random.learning.clojure.overridex
  (:refer-clojure :exclude [sorted?]))

(defn sorted? [coll]
  {:pre [ (coll? coll)]}
  (clojure.core/sorted? coll))

I'm using Eclipse+counterclockwise, so loading this namespace(Ctrl+Alt+L) first time gives no warnings/errors, loading it second time, one warning and no errors, and subsequent times it's loaded there are no errors/warnings.

the warning is this:
WARNING: sorted? already refers to: #'clojure.core/sorted? in namespace: random.learning.clojure.overridex, being replaced by: #'random.learning.clojure.overridex/sorted?

I could ignore the warning, no problem, but then I try to use this namespace in another namespace:

(ns random.learning.clojure.usetheoverridexns
  (:use random.learning.clojure.overridex)
  )

(and
  (= false (sorted? '(1 2)))
  (= true (sorted? (sorted-set 1 2))))


When I load this namespace first time I get:
WARNING: sorted? already refers to: #'clojure.core/sorted? in namespace: random.learning.clojure.usetheoverridexns, being replaced by: #'random.learning.clojure.overridex/sorted?
true
I could ignore that, but then I load it again(and any subsequent time) and this is an error (not just a warning that can be ignored):

IllegalStateException sorted? already refers to: #'random.learning.clojure.overridex/sorted? in namespace: random.learning.clojure.usetheoverridexns  clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)

Notice there's no "true" aka return value.

When I actually close the REPL, and Ctrl+Alt+L load only this latter namespace I get this:

;; Clojure 1.5.0-RC16
;; Switching to random.learning.clojure.usetheoverridexns namespace
WARNING: sorted? already refers to: #'clojure.core/sorted? in namespace: random.learning.clojure.usetheoverridexns, being replaced by: #'random.learning.clojure.overridex/sorted?
true
IllegalStateException sorted? already refers to: #'random.learning.clojure.overridex/sorted? in namespace: random.learning.clojure.usetheoverridexns  clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)


and any subsequent loads, show only the part in bold.

 While this may be some ccw issue, I am probably also doing something wrong that I could be doing better.
 What is the way to do this? especially in the latter namespace which is using the namespace which has overridden the sorted?
 I do want the overridden "sorted?" to actually be available and override the clojure.core/sorted? in any namespaces that are using the overridex namespace.


Thank you.

--
Please correct me if I'm wrong or incomplete,
even if you think I'll subconsciously hate it.

Anthony Grimes

no leída,
14 feb 2013, 13:52:4414/2/13
a clo...@googlegroups.com
The problem is that your first namespace defines 'sorted?' and your second namespace just uses the namespace, thus overriding 'sorted?'. You have two options here. Your biggest project is that you're using ':use'. Use ':require' instead. Something like `(:require [random.learning.clojure.overridex :as overridex])`. Your second option is to do the :refer-clojure dance in this namespace as well, but really you should just use :require and qualify the namespace.

AtKaaZ

no leída,
14 feb 2013, 14:26:1714/2/13
a clo...@googlegroups.com
Thank you for replying.

I see that using :require like (:require [random.learning.clojure.overridex :as o])
also means I have to use sorted? as  "o/sorted?" else the clojure.core/sorted? is used
or using (:require [random.learning.clojure.overridex])  means I've to use "random.learning.clojure.overridex/sorted?".
This is actually something I was trying to avoid. I mean, I still want to use just "sorted?" and simply by somehow including another namespace (require/use/refer whichever way) in my namespace declaration then the implementation of "sorted?" would be different as dictated by this included namespace (supposed I could switch between the two, or even just not include any and have it be clojure.core variant of "sorted?")

What I forgot to mention is that I've tried the (:refer-clojure :exclude [sorted?]) variant in the new namespace but I was still unable to get rid of the errors. But maybe this is now just a ccw bug and this is indeed the right way for me to do thing if I really wanted the behavior that I mentioned.

(ns random.learning.clojure.usetheoverridexns
  (:refer-clojure :exclude [sorted?])
  (:use random.learning.clojure.overridex)
  (:refer-clojure :exclude [sorted?])

  )

(and
  (= false (sorted? '(1 2)))
  (= true (sorted? (sorted-set 1 2))))


First time loading this in a new repl yields:

;; Clojure 1.5.0-RC16
;; Switching to random.learning.clojure.usetheoverridexns namespace
true
IllegalStateException sorted? already refers to: #'random.learning.clojure.overridex/sorted? in namespace: random.learning.clojure.usetheoverridexns  clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)

it's not too bad, and any successive loads just show true

The only thing is that if I switch to another namespace while repl is running I can't ever switch back due to the error:
;; Switching to random.learning.clojure.overridex namespace
nil
=> *ns*
#<Namespace random.learning.clojure.overridex>
;; Switching to random.learning.clojure.usetheoverridexns namespace

IllegalStateException sorted? already refers to: #'random.learning.clojure.overridex/sorted? in namespace: random.learning.clojure.usetheoverridexns  clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)
=> *ns*
#<Namespace random.learning.clojure.overridex>

So, I'll keep using this variant (:refer-clojure :exclude [sorted?])  for now,

thank you Anthony.

Btw, is there a way to not implicitly include clojure.core or to have it aliased :as cc for example so that I would have to always cc/sorted? if I wanted to use clojure.core  and any others from it ?
 Even if this were possible, I wouldn't be able to just plug in a different implementation of "sorted?" and easily choose between the: namespace1, namespace2 and clojure.core  's implementation of "sorted?" because I would have to at least change from cc/sorted? to nsany/sorted? where depending on which namespace I import they can be aliased ":as nsany" but clojure.core would always be a different alias ":as cc".

thx


--
--
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
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos