Details
-
Type:
Defect
-
Status:
Closed
-
Priority:
Major
-
Resolution: Declined
-
Affects Version/s: Release 1.2, Release 1.3
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
-
Approval:Not Approved
Description
The following produces a NullPointerException:
(defprotocol Foo (act [this]))
(defrecord Fred []
Foo
(act [this] (println "done.")))
(defrecord Bar [act] ;; <<<<<======= Field name is the same as method name.
Foo
(act [this] (act (Fred.)))) ;; <<<<<====== Behaves as (nil (Fred.))
(act (Bar. nil))
Produces:
Exception in thread "main" java.lang.NullPointerException
at protocol.Bar.act(protocol.clj:8)
at protocol$eval66.invoke(protocol.clj:9)
at clojure.lang.Compiler.eval(Compiler.java:6465)
at clojure.lang.Compiler.load(Compiler.java:6902)
at clojure.lang.Compiler.loadFile(Compiler.java:6863)
at clojure.main$load_script.invoke(main.clj:282)
at clojure.main$script_opt.invoke(main.clj:342)
at clojure.main$main.doInvoke(main.clj:426)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:401)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.Var.applyTo(Var.java:518)
at clojure.main.main(main.java:37)
–
The following works as expected:
(defprotocol Foo (act [this]))
(defrecord Fred []
Foo
(act [this] (println "done.")))
(defrecord Bar [x] ; <<== Field name is the DIFFERENT than method name
Foo
(act [this] (act (Fred.))))
(act (Bar. [1 2 3]))
Produces:
"done."
–
The following also works:
(defprotocol Foo (act [this]))
(defrecord Fred [])
(defrecord Bar [act]) ; <<== Field name is the same as method name
(extend-protocol Foo
Fred
(act [this] (println "done."))
Bar
(act [this] (act (Fred.))))
(act (Bar. [1 2 3]))
Declined since this is not really a bug. There is a work-around and no obvious solution to the more general problem of defrecord name collisions. If this still bugs you, please feel free to bring it up on clojure-dev, and we'll open a new ticket once a discussion has been had.