In a file I can do this:
(:require [clojurewerkz.neocons.rest :as nr])
how can I import this into the repl and still be able to refer to it by 'nr'?
thanks
Lee's answer is right, of course, but why do you need to quote? The vector [...] is evaluated and the values inside too, and here both clojurewerkz.neocons.rest and nr are treated as variables, which are unbound (you do have an error message, don't you?). You can also choose to quote the symbols:
(require ['clojurewerkz.neocons.rest :as 'nr])
This also means that you could require namespaces dynamically, if you pass a variable.
But then, why don't you need to quote inside a file? I suppose that this is because the (require ... ) found in your file is enclosed in an ns macro, and as such, the forms are not evaluated. See require.
You can use require and quote the vector:
(require '[clojurewerkz.neocons.rest :as nr])
Related
I'm just getting started with clojure and core.typed, and keep running into the following error when I evaluate (check-ns 'stocks.db) with the following code:
(ns stocks.db
(:gen-class)
(:require [clojure.core.typed :refer [ann HMap]]))
(use '[datomic.api :only [q db] :as d])
(ann break-me [String -> (HMap)])
(defn break-me
"Do I break cored.typed?"
[]
{:db/id #db/id[:db.part/db]})
ExceptionInfo No reader function for tag id clojure.core/ex-info (core.clj:4327)
(break-me) evaluates to {:db/id #db/id[:db.part/db -1000000]} as you'd expect.
Similarly to this unanswered question, the offending term is definitely #db/id.
Thanks for any help.
I'm new to Clojure and Datomic but, I think you need to generate your temporary id with the tempid function that's part of the Datomic API (see http://docs.datomic.com/clojure/index.html#datomic.api/tempid).
So it'd look like this:
(ns stocks.db
(:gen-class)
(:require [clojure.core.typed :refer [ann HMap]]))
(use '[datomic.api :only [q db] :as d])
(ann break-me [String -> (HMap)])
(defn break-me
"Do I break cored.typed?"
[]
{:db/id (tempid :db.part/db)})
I'm having similar issues with clojure.edn/read-string, I haven't quite figured it out. Hope that works for you.
UPDATE:
In this code: https://github.com/Datomic/codeq/blob/master/src/datomic/codeq/core.clj the Datomic folks seem to be doing just what you are. So while in your case I think using tempid will work, I think there's a deeper issue, and it seems like it has to do with the literal #db/id.
UPDATE:
Here: https://github.com/Datomic/day-of-datomic/blob/master/samples/literals_vs_code.clj using tempid rather than literals is recommended.
UPDATE:
I've found a solution that also resolves my issue. I was trying to read in my schema from a file: schema.edn using clojure.edn/read-string after reading the contents as a string using clojure.core/slurp and got similar error complaining about the #db/id literal.
I implemented the read-all and transact-all functions found here: https://github.com/Datomic/day-of-datomic/blob/053b3bd983d165b8fa7c0c039712fb1cb75eddf3/src/datomic/samples/io.clj and it works fine. It seems like there are some sneaky issues with using the reader to parse #db/id literals, still haven't figured out exactly why.
UPDATE:
This is using a Clojure feature called "tagged literals" which allows you to define a map of "data readers" in a file named data_readers.clj at the root of your classpath that should contain a map of tag names and vars that will parse the arguments to the tag.
So with this data_readers.clj file:
{minutes my.project/to-minutes
seconds my.project/to-seconds}
You can do this:
#minutes 3
#seconds 4
You can read about tagged literals at the bottom of this page: http://clojure.org/reader.
However, I still have not figured out the reason for the issue with the #db/id tagged literal. I've posted a question on the Clojure group forum here: https://groups.google.com/forum/#!topic/datomic/Fi7iXps2npw. Update: Ben Kamphaus provides a nice explanation there.
I am learning clojure now, I wrote a file like this:
;; File ./mycode/myvoc.clj
(ns mycode.myvoc
(:use 'clojure.java.io)
(:import (java.io.File)))
; more code here...
this file resides in ./mycode/, when I run REPL, I wanna use the function in myvoc.clj, like this:
user=> (use 'mycode.myvoc)
java.lang.Exception: lib names inside prefix lists must not contain periods (myv
oc.clj:1)
I don't know why. if I change myvoc.clj as :
(ns mycode.myvoc)
; (:use 'clojure.java.io)
; (:import (java.io.File)))
It'll be ok but just report no "reader in this context" for I commented the import part.
Could somebody fix this? I alse use require but get the same kind of error.
You need to remove the quote from your :use clause:
(ns mycode.myvoc
(:use clojure.java.io) ; note no '
(:import java.io.File)) ; extra parens removed here; they do no harm,
; though
'clojure.java.io is shorthand for (quote clojure.java.io), so your original :use clause was
(:use (quote clojure.java.io))
This looks as if you were trying to :use a namespace with a prefix of quote and final segment clojure.java.io. The dots in the latter are the direct cause of the error from the point of view of ns.
Incidentally, it's much more usual to (:require [clojure.java.io :as io]) and then say io/file, io/reader etc. than it is to pull in the entire namespace.
Finally, just to be clear, the quote is necessary when using the function use (like in your (use 'mycode.myvoc) call), as opposed to a :use clause in a ns declaration.
I'm looking at the example code in Ch 16 of the book "Clojure Programming" by Emerick, Carper, and Grand, and I see
(ns com.clojurebook.url-shortener
(:use [compojure.core :only (GET PUT POST defroutes)])
(:require (compojure handler route)
[ring.util.response :as response]))
I'm having some trouble mentally parsing the :require clause and would appreciate some help. The first form in the clause, namely (compojure handler route), would appear to be a Prefix List, as recorded in the documentation here. However, it doesn't fit the definition of a prefix list, in that
A prefix list contains the shared prefix followed by libspecs
with the shared prefix removed from the lib names.
But the usage in the book has three symbols, none of which look like a shared prefix. Furthermore,
After removing the
prefix, the names that remain must not contain any periods.
The usage in the book has a remaining name, ring.util.response, with periods in it.
Therefore the term
(:require (compojure handler route)
[ring.util.response :as response])
isn't a prefix list. Then what is it? I can't find a match in the documentation for :require.
Here, you're requiring two things, one of which is a prefix list and the other is a require with options. They are handled independently, which sounds like is where you're getting confused.
The first part (compojure handler route), is a prefix list. The second part [ring.util.response :as response], is a normal libspec, not a prefix list. You can add additional prefix lists and libspecs as needed.
As noted in deterb's answer, the (compojure handler route) is a prefix list - compojure is the common prefix shared by the namespaces to require, and handler and route are the child libspecs. The combining . is implicit.
(:require (compojure handler route))
is equivalent to:
(:require [compojure.handler]
[compojure.route])
You can use symbols as libspecs when there are no additional options, so that could also be written:
(:require compojure.handler
compojure.route)
But when requiring multiple namespaces, I find it more readable to use all vectors rather than a mix of vectors and symbols.
require is also a function in clojure, if you check the source of that function
(defn require[& args]
(apply load-libs :require args))
So, require will take an arbitrary number of libspecs, such as the quoted symbol and vector we’ve just seen. You can also mix and match symbols with vectors. The main thing to remember here is that a libspec should be either a quoted symbol or vector. So whenever you want to use something like :as, that thing (the libspec) should be a vector.
What is the difference between ; and ;; when starting a comment in Clojure? I see that my text editor colours them differently, so I'm assuming there is notionally some difference.
I also see that Marginalia treats them differently:
; Stripped entirely
;; Appears in text section of marginalia
(defn foobar []
; Appears in code section of marginalia output
;; Again, appears in code section of marginalia output
6)
There is no difference as far as the interpreter is concerned. Think of ; ;; ;;; and ;;;; as different heading levels.
Here is my personal use convention:
;;;; Top-of-file level comments, such as a description of the whole file/module/namespace
;;; Documentation for major code sections (i.e. groups of functions) within the file.
;; Documentation for single functions that extends beyond the doc string (e.g. an explanation of the algorithm within the function)
; In-line comments possibly on a single line, and possibly tailing a line of code
Check out the official description of the meaning of ; vs ;; in elisp: since the Clojure indenter is basically the same, it will treat them similarly. Basically, use ; if you are writing a long sentence/description "in the margins" that will span multiple lines but should be considered a single entity. Their example is:
(setq base-version-list ; there was a base
(assoc (substring fn 0 start-vn) ; version to which
file-version-assoc-list)) ; this looks like
; a subversion
The indenter will make sure those stay lined up next to each other. If, instead, you want to make several unrelated single-line comments next to each other, use ;;.
(let [x 99 ;; as per ticket #425
y "test"] ;; remember to test this
(str x y)) ;; TODO actually write this function
Emacs ; to be used for end-of-line comments and will indent in surprising ways if that is not your intent. ;; does not so I usually use ;;.
Clojure doesn't care - any line is ignored from the ; to EOL.
I believe there is a tradition in CL of using increasing numbers of ; to indicate more important comments/sections.
no meaning for the language. ; is a reader macro for comment
perhaps other tools parse them but "within clojure" they are the same.
There is no difference from a Clojure-perspective. I find that ;; stands out a little better than ;, but that's only my opinion.
Marginalia on the other hand treats them differently because there are times when a comment should remain in the code section (e.g. license) and those are flagged with ;. This is an arbitrary decision and may change in the future.
In emacs lisp modes including clojure-mode, ;; is formatted with the convention of being at the beginning of a line, and indented as as any other line, based on the context. ; is expected to be used at the end of a line, so emacs will not do what you want it to if you put a single-semicolon comment at the beginning of a line expecting it to tab to the indentation for the present context.
Example:
(let [foo 1]
;; a comment
foo) ; a comment
I'm not sure (not used Clojure and never heard of this before), but this thread might help.
In ruby I frequently use File.expand_path(File.dirname(__FILE__)) for loading config files or files with test data. Right now I'm trying to load some html files for a test in my clojure app and I can't figure out how to do it without hard coding the full path to the file.
edit:
I'm using leinigen if that helps in any way
ref: __FILE__ is a special literal which returns the filename (including any path) given to the program when executed. see (rubydoc & perldata)
*file*
API Reference (add *file* to the url)
Here is one way to replicate that in Clojure:
(defn dirname [path]
(.getParent (java.io.File. path)))
(defn expand-path [path]
(.getCanonicalPath (java.io.File. path)))
Then your Ruby line File.expand_path(File.dirname(__FILE__)) in Clojure would be this:
(expand-path (dirname *file*))
See Java interop docs for .getParent & .getCanonicalPath.
NB. I think *file* always returns the absolute (though not canonical) pathname/filename in Clojure. Whereas __FILE__ returns the the pathname/filename provided at execution. However I don't think these difference should effect what your trying to do?
/I3az/
Neither of the 9 point solutions is correct. *file* gives you a file relative to the classpath. Using .getCanonicalPath or .getAbsolutePath on *file* will give you a nonexistant file. As pointed out in this old thread, you need to use ClassLoader to resolve *file* correctly. Here's what I use to get the parent directory of the current file:
(-> (ClassLoader/getSystemResource *file*) clojure.java.io/file .getParent)
Based on user83510's answer above, the full answer is:
(def path-to-this-file
(clojure.string/join "/" [(-> (ClassLoader/getSystemResource *file*) clojure.java.io/file .getParent) (last (clojure.string/split *file* #"/"))]))
It ain't pretty but it works :P