Noob question, using Win7 64-bit, Clojure 1.2.0, Java 1.6.0_22
When I start clojure from command line, pprint function is easily available.
user=> pprint
#<pprint$pprint clojure.pprint$pprint#16dfa45>
user=> (pprint "hi")
"hi"
nil
user=>
But when I try to use pprint from a file, I get an error. This happens with and without namespace (ns... :require...) as shown in pprint documentation
clj file as follows:
(ns whatevah
(:require clojure.pprint))
(pprint "hi")
Error as follows:
C:\Users\mischw\code\Clojure>java -cp ";c:\users\mischw\code\clojure\classes\*;c:\Program Files (x86)\Java\SWT;c:\users\mischw\code\clojure\classes\bookcode\*" clojure.main swinglearn.clj
Exception in thread "main" java.lang.Exception: Unable to resolve symbol: pprint in this context (swinglearn.clj:14)
... 21 more
Output completed (0 sec consumed) - Normal Termination
I don't understand the general idea of what's going on here. Why does one work but not the other? Does that have to do with namespaces? Classpaths? Some other simple fix? Clearly noob questions, but I find this happens with a bunch of examples... I'm unable to run them even though it seems straightforward to import/use/require/include them.
You're getting require mixed up with use and/or import. require causes the library to get loaded, and every public symbol it exports will be accessible as eg clojure.pprint/pprint. If you want to use a more convenient name like just pprint, you need to refer to the namespace. use is a convenient shorthand for "require, then refer", to load the library without the namespace prefix.
user> (ns user (:require clojure.pprint))
nil
user> (pprint 1)
; Evaluation aborted.
user> (clojure.pprint/pprint 1)
1
nil
user> (ns user (:use clojure.pprint))
nil
user> (pprint 1)
1
Edit: Not sure why it's working for you from the REPL. As you can see, it doesn't work for me. I imagine you did some setup earlier that makes it work and then forgot about it, or possibly you have some init script that does this stuff for you at the REPL but not when loading from a file.
Here are a couple of examples:
;;how to use it with :require and :use
;; :require
(ns example.pprinter
(:require [clojure.pprint :as pp]))
(def myname "John Smith")
(pp/pprint myname)
;; :use
(ns example.pprinter
(:use clojure.pprint))
(def myname "John Smith")
(pprint myname)
Related
I'm importing ajax.edn in my cljs project like so:
(:require [ajax.edn :as edn])
However, I'm getting the following error:
ajax.edn isn't available.
I do have cljs-ajax/cljs-ajax in my deps.edn like so:
cljs-ajax/cljs-ajax {:mvn/version "0.8.1"}
How to fix this error?
I am stuck with creating a macro for clojurescript. Can you give a step-by-step instruction on how to include a macro in clojurescript? The folder structure I am looking for is like this
+ src/
| clj/
| test_app/
| macros.clj
| cljs/
| test_app/
| example.cljs
| project.clj
Can you give an example for each of the 3 files? I am looking for a solution that is compatible with lein cljsbuild auto .
This is a macro that allows you to include files in cljs at compile time. For example, when doing i18n, I save all the language strings on a translations.edn file. I then include it at compile time using a macro in /clj/test_app/macros.clj:
(ns test-app.macros
(:import java.io.File))
(defmacro load-edn
"Reads a file and returns it as a string"
[relative-path]
(slurp relative-path))
In cljs/test_app/example.cljs
(ns test-app.example
(:require [cljs.reader :as reader])
(:require-macros [test-app.macros :as m])
(:use [net.unit8.tower :only [t]]))
(def i18n (reader/read-string (m/load-edn "resources/lang/translations.edn")))
(defn lang-map
"Wrapper around tower's t adding the configuration map"
[language & args]
(apply t language i18n args))
This should work if you start from cljs-kickoff [1] and add [net.unit8/tower-cljs "0.1.0"] to your dependencies.
[1] https://github.com/konrad-garus/cljs-kickoff
I have a .clj file that starts like this :
(ns clojure_crawl.core)
(require '[clj-http.client :as client])
(use 'clojure.contrib.json)
Followed by several function definitions :
(defn f1 [] "" (+ 1 1))
(defn f2 [] "" (+ 2 2))
etc...
However, when I run the command "(use 'myfile.core :reload)"
Some of my functions , although visible at the REPL, cannot run do to "missing namespace" errors.
How do I add the dependencies so that the REPL can run any of the functions defined in my file ?
If your code is in "clojure_crawl/core.clj", its namespace should be clojure-crawl.core (note the hyphen). See http://clojure.org/libs
As Joost already said, you have to be careful with hyphens and underscores: wherever you use a hyphen in your namespace names, replace it with an underscore in the corresponding file/directory names (and vice versa).
Also, the use of the require and use functions in clj source files is discouraged. Instead, declare the libraries you need directly in the ns macro:
(ns clojure-crawl.core
(:require [clj-http.client :as client])
(:use clojure.contrib.json))
This also takes the burden of properly quoting the required namespaces from you.
Using SBCL, I'm writing a small server and I would like to trace the server thread, but when I use mclide/swank, I do not see any output from the server thread.
? (require 'sb-posix)
NIL
? (sb-thread:make-thread (lambda () (format t "hi from the thread")))
?
When I try the same thing from sbcl directly, I see what I expect:
(require 'sb-posix)
; loading system definition from
; /opt/local/var/macports/software/sbcl/1.0.39_0+html+threads/opt/local/lib/sbcl/sb-grovel/sb-grovel.asd
; into #
; registering # as SB-GROVEL
("SB-POSIX" "SB-GROVEL" "ASDF")
(sb-thread:make-thread (lambda () (format t "hi from the thread")))
hi from the thread#
*
Does swank have issues capturing standard output from non-foreground threads? If I used slime, would this kind of thing work?
I'm relatively new to Clojure and a complete HTML/Compojure virgin. I'm trying to use Compojure to create static pages of HTML using a function similar to this:
(defn fake-write-html
[dir args]
(let [file (str dir *file-separator* *index-file*)
my-html (html
(doctype :html4)
[:html
[:head
[:title "Docs and Dirs:"]]
[:body
[:div
[:h2 "A nice title"]]
[:div
[:ul
[:li "One"]
[:li "Two"]]]]])]
(clojure.contrib.duck-streams/spit file my-html)))
The function just writes HTML to a file. (The args argument is irrelevant here. Just there to assure the example compiles and runs in my program.)
"Programming Clojure" indicated that the call to the html function would produce formatted HTML -- multiple lines with indentation. All I get is the doc type as expected followed by all of the HTML on a single line. HTML Tidy doesn't find any issues with the content of the output file. It comes out as a single line if I println it at the REPL too.
Is there something else needed to get formatted output?
The formatting of HTML output in Compojure was removed for performance and complexity reasons. To get formatted output you will probably have to write your own printer function.
I usually output HTML as Compojure sees fit and use Firebug to view it live in my browser. Firebug will display it nicely formatted no matter if it's really all on one line or not. This works well enough most of the time. If you need to serialize this HTML in a readable form, you could keep it as Clojure vectors and sexps and serialize it that way.
Although Brian's answer pointed me to Firebug, enabling the debugging I wanted, I was just to obsessive-compulsive to leave it alone. Following up on kwertii's pointer to JTidy, I included the following code in my program.
Edit: Simplified the code somewhat
(ns net.dneclark.someprogram
(:gen-class)
...
(:import (org.w3c.tidy Tidy))
)
...
(defn configure-pretty-printer
"Configure the pretty-printer (an instance of a JTidy Tidy class) to
generate output the way we want -- formatted and without sending warnings.
Return the configured pretty-printer."
[]
(doto (new Tidy)
(.setSmartIndent true)
(.setTrimEmptyElements true)
(.setShowWarnings false)
(.setQuiet true)))
(defn pretty-print-html
"Pretty-print the html and return it as a string."
[html]
(let [swrtr (new StringWriter)]
(.parse (configure-pretty-printer) (new StringReader (str html)) swrtr)
(str swrtr)))
I added the jtidy-r938.jar to my project (NetBeans using the enclojure plugin) and imported it. The configuration function tells the parser to output formatted, indented HTML and skip the warnings. The return value from the pretty-printer function is now nicely formatted whether I open it with Firebug or a simple text editor.
There are tons of HTML pretty printers available for Java, notably JTidy, a Java port of HTML Tidy. You can easily feed Clojure's output through this library programatically and get neatly indented and formatted HTML back.
HTML Tidy is also available as a command-line program for Unix if you'd care to go that route -- you can just pipe your HTML through it like any other shell program.
The above did not work for me.
I changed this a bit.
add this [jtidy "4aug2000r7-dev"] to project.clj
(:use clojure.core)
(:import (org.w3c.tidy Tidy))
(:import (java.io ByteArrayInputStream ByteArrayOutputStream)))
(defn configure-pretty-printer
"Configure the pretty-printer (an instance of a JTidy Tidy class) to
generate output the way we want -- formatted and without sending warnings.
Return the configured pretty-printer."
[]
(doto (new Tidy)
(.setSmartIndent true)
;(.setTrimEmptyElements true)
(.setShowWarnings false)
(.setQuiet true)))
(defn pretty-print-html
"Pretty-print the html and return it as a string."
[html]
(let [swrtr ( ByteArrayOutputStream.)]
(.parse (configure-pretty-printer) (ByteArrayInputStream. (.getBytes (str html))) swrtr)
(str swrtr)))
If anyone is still looking at this query, you need the hiccup library. If formats HTML from exactly the Clojure data structure shown.
So
(require '[hiccup.core :refer [html]])
(defn fake-write-html
[dir args]
(let [file (str dir *file-separator* *index-file*)
my-html (html
[:html
[:head
[:title "Docs and Dirs:"]]
[:body
[:div
[:h2 "A nice title"]]
[:div
[:ul
[:li "One"]
[:li "Two"]]]]])]
(clojure.contrib.duck-streams/spit file my-html)))
will work exactly as the original poster intended. Strongly recommended.