2011-01-02 20 views
13

he creado un disco como este:no pueden importar registros clojure

(defrecord User [user-id email]) 

: pero cuando intento acceder a él desde otro espacio de nombres me sale el error:

(User. "name" "email") 

java .lang.IllegalArgumentException: No se puede resolver nombre de clase: usuario

funciona cuando lo haga:

(oe.model.modelcore.User. "name" "email") 

: Yo sé que voy a necesitar importar la clase de Java, pero ¿hay alguna manera para clojure hacer esto automáticamente cuando lo haga:

(use 'oe.model.modelcore :reload) 

Respuesta

13

Técnicamente debe requerirlo (no necesariamente debe usarlo) para que el archivo que contiene la definición del registro se compile y se cree la clase. Luego debe importarlo para que esté disponible para construir como una clase Java. Si crea una función de constructor en las primeras ns como

(defn new-user [id email] 
    (User. id email)) 

, entonces no tendrá que importarla en la llamada ns.

escribí esto hace un tiempo aquí:

+3

Afortunadamente, eso no es más necesario comenzar con Clojure 1.3, donde los registros se convirtieron en ciudadanos de primera clase. Solo quería dejar un comentario para las personas que leen esto ahora. –

+0

Desde mi experiencia necesitas compilar AOT, y ambos requieren e importan registros. (Por supuesto que estábamos usando la biblioteca de esquemas de prismáticos para validar nuestros registros) –

9

Usted tiene que importar el registro de la siguiente manera:

(ns some-ns 
    (:import [oe.model.modelcore User])) 
+0

me cambió la respuesta aceptada a esta ya que esta era la respuesta que trabajó para mí en enero de 2014 – Zubair

8

En su pregunta va a crear un registro, a continuación, invocar el constructor de la clase generada como un efecto secundario. Para hacerlo, debes importar esa clase como se menciona en otra respuesta.

Sin embargo, en el camino preferido (desde Clojure 1.4) es utilizar las funciones de constructor generadas por defrecord (aquí se llamarán ->User y map->User). Estas funciones le permiten evitar las formas de interoperabilidad y simplemente hacer referencia en las funciones del constructor como cualquier otra función. Al evitar la interoperabilidad, esta es una solución menos-hosty más portátil:

(ns some-ns 
    (:require [oe.model.modelcore :refer (->User)])) 

(def user (->User "name" "email")) 
7

que podría ser muy difícil si usted tiene - (guión) en su espacio de nombres.

As it turns out there were two errors:

– Importing defrecord from another namespace is not just :use. I had to first :require the namespace, then import the defrecord. This was a trivial problem to solve and I figured it out quickly. Only this did not work in my case

– Dashes “-” and Underscores “_” are a nuisance since we are mixing Lisp with Java. While the file system uses underscores Clojure converts things to dashes. Brilliant.

So to fix the second error I use the follow in the ns block

(ns adder.core 
    (:require building-blocks.activity) 
    (:import [building_blocks.activity Activity])) 

https://cyrax.wordpress.com/2013/07/22/clojure-importrequireuse-defrecord-from-another-namespace/

+1

+1 El tema de subrayado en: import es lo que todavía me estaba molestando, así que gracias por agregar esto mucho después de que OP acepte una respuesta. –

+0

¡Perdón por la devolución, es por error y no puedo recuperarlo! – Aspasia

+0

Presiona la votación :) – MAGx2

Cuestiones relacionadas