Following a previous question where I asked on how on earth do sessions work in Clojure, I have been experimenting with Monger.
In the documentation, you can find the code snippet:
(ns monger.docs.examples
(:require [monger.core :as mg]
[monger.ring.session-store :refer [monger-store]]))
;; create a new store, typically passed to server handlers
;; with libraries like Compojure
(let [conn (mg/connect)
db (mg/get-db conn "monger-test")]
(monger-store db "sessions"))
which is helpful, but I don't know how to implement the handler. Is there anyone who explain how this would work interacting with a handler, or being embedded in a handler itself?
EDIT:
So far I've tried:
(def app-handler
(let [{:keys [_ db]} (mg/connect-via-uri (env :mongo-uri))]
(-> handler
(session/wrap-session {:store (session-store db "sessions")}))))
but get:
java.lang.ClassCastException: class java.lang.String cannot be cast to class clojure.lang.Associative (java.lang.String is in module java.base of loader 'bootstrap'; clojure.lang.Associative is in unnamed module of loader 'app')
So, it obviously doesn't like the mapping in-front, but this is the pattern I've seen everywhere else. Any ideas are (and explanations) would be wonderful!
What is handler? Can you add a bit more code of what you tried?
According to the error message somewhere you return a string, where a map is expected.
Note that session-store should return an implementation of ring.middleware.session.store/SessionStore. See wrap-session.
Related
I am wondering how one writes macros in Common Lisp that allow him to part with Lisp forms in calls to the former.
For instance, suppose I have the following macro:
(defmacro define-route ((app uri method) &body body)
`(setf (ningle:route ,app ,uri :method ,method)
,#body))
A call to it would look something like this:
(define-route (*app* "/" :GET)
(print "Welcome to ningle using GET!"))
What if one wanted to write a macro that could be called like this:
#route(*app*, "/", :GET)
or like this:
route: *app*, "/", :GET
Is this possible? I have seen the #route syntax somewhere before but am not sure how to implement it, nor do I remember what it was called to look it up again.
We encounter this decorator syntax (or annotations in CL) in the Caveman or Lucerne web frameworks:
#route GET "/"
(defun index ()
(render #P"index.tmpl"))
I doubt you can do route: *app*, "/", :GET.
cl-annot is a general annotation library for CL.
It is a reader macro, more examples here: http://lisp-lang.org/wiki/article/reader-macros
ps: Snooze, by the author of Sly (and yasnippet), is a web frameworks that treats routes as usual functions, thus route parameters as usual function arguments. It also has built-in reporting of errors (in browser, in the debugger, with a custom 404 page). I liked it better than the two mentioned. No big experience with either of them.
I have 2 files: enviro.clj and point.clj; both in the same folder.
I want to import point.clj into enviro.clj.
enviro.clj:
(ns game-of-life.enviro
(:require [game_of_life.point :as point]))
(defrecord Enviro [cells dims])
(defn create-dead-enviro [width height]
(Enviro.
(replicate (* width height) :dead)
(point/Point. width height)))
point.clj:
(ns game-of-life.point)
; A 2D point representing a coordinate, or any pair of numbers
(defrecord Point [x y])
With this set-up though, Intellij (with Cursive) is saying that it can't resolve point/Point. inside of create-dead-enviro. It does however suggest importing it. If I allow it to auto-fix it, it changes the top of enviro.clj to:
(ns game-of-life.enviro
(:require [game_of_life.point :as point])
(:import (game_of_life.point Point)))
From what I've read though, import is only for Java interop to import a Java class; it's not used to "import" a Clojure namespace.
What am I missing here?
Edit
Still no. I changed enviro.clj to:
(ns game-of-life.enviro
(:require [game_of_life.point :as point]))
(defrecord Enviro [cells dims])
(defn create-dead-enviro [width height]
(Enviro.
(replicate (* width height) :dead)
(->Point width height)))
And I'm still getting an "cannot resolve" error.
This is a bit of specialness around records and only records where you need to import them if you want to use the (recordName. args) java interop constructor form.
if you use the ->Enviro helper function you don't need to add the extra import.
user> (defrecord Enviro [cells dims])
user.Enviro
user> (->Enviro 1 2)
#user.Enviro{:cells 1, :dims 2}
and it's a bit more clojure'ish do do it that way anyway.
Recort types are a quick way to define a named type to interacting with java libraries that expect this. They are also slightly faster for field access than maps. When using records keep in mind that if you conj some extra field into them in the course of working with them, then remove it later, they will silently stop being records and revert back to being normal maps. In general use records when you know you need them for java interop or in very tightly optimized code that you have already very carefully benchmarked (I have never seen this in practice). They have some value for documentation as well.
here is an example of using the ->recordName function instead of the java interop form.
user> (ns game-of-life.point)
nil
game-of-life.point> (defrecord Point [x y])
game_of_life.point.Point
game-of-life.point> (in-ns 'user)
#namespace[user]
user> (require '[game-of-life.point :as point])
nil
user> (point/->Point 1 2)
#game_of_life.point.Point{:x 1, :y 2}
Because the java interop form generates a names class outside the usual namespace onventions you need to import that class iff you use the className. constructor or use an explicit call to new to create your record object. if you use the automatically created function ->className then you don't need to use import
I'm trying to implement the ideas from http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded into my codebase.
I have a dao layer, where I now need to pass in a database in order to avoid global state. One thing that is throwing me off is the phrase:
Any function which needs one of these components has to take it as a
parameter. This isn't as burdensome as it might seem: each function
gets, at most, one extra argument providing the "context" in which it
operates. That context could be the entire system object, but more
often will be some subset. With judicious use of lexical closures, the
extra arguments disappear from most code.
Where should I use closures in order to avoid passing global state for every call? One example would be to create an init function in the dao layer, something like this:
(defprotocol Persistable
(collection-name [this]))
(def save nil)
(defn init [{:keys [db]}]
(alter-var-root #'save (fn [_] (fn [obj] (mc/insert-and-return db (collection-name obj) obj WriteConcern/SAFE)))))
This way I can initiate my dao layer from the system/start function like this:
(defn start
[{:keys [db] :as system}]
(let [d (-> db
(mc/connect)
(mc/get-db "my-test"))]
(dao/init d)
(assoc system :db d)))
This works, but it feels a bit icky. Is there a better way? If possible I would like to avoid forcing clients of my dao layer to have to pass a database every time it uses a function.
You can use higher order function to represent your DAO layer - that's the crux of functional programming, using functions to represent small to large parts of your system. So you have a higher order function which takes in the DB connection as param and return you another function which you can use to call various operations like save, delete etc on the database. Below is one such example:
(defn db-layer [db-connection]
(let [db-operations {:save (fn [obj] (save db-connection obj))
:delete (fn [obj] (delete db-connection obj))
:query (fn [query] (query db-connection query))}]
(fn [operation & params]
(-> (db-operations operation) (apply params)))))
Usage of DB layer:
(let [my-db (create-database)
db-layer-fn (db-layer my-db)]
(db-layer-fn :save "abc")
(db-layer-fn :delete "abc"))
This is just an example of how higher order functions can allow you to sort of create a context for another set of functions. You can take this concept even further by combining it with other Clojure features like protocols.
I am trying to write a wrapper for the google adwords api in Clojure but struggle with constants and Interfaces.
The java code looks like this :
CampaignServiceInterface campaignService =
user.getService(AdWordsService.V201109.CAMPAIGN_SERVICE);
Usually you can call constants in Clojure with e.g. (Math/PI) but when I write:
(def user (AdWordsUser. ))
(.getService user (AdWordsService/V201109/CAMPAIGN_SERVICE))
I just get "no such namespace".
Also I am a bit clueless on how to implement the interface correct. I think I should use "reify" but I get stuck.
Link to Interface:
http://google-api-adwords-java.googlecode.com/svn-history/r234/trunk/docs/com/google/api/adwords/v201003/cm/CampaignServiceInterface.html
(defn campaign-service [ ]
(reify
com.google.adwords.api.v201109.cm.CampaignServiceInterface
(get [this] ??))))
If I read it correctly, AdWordsService.V201109.CAMPAIGN_SERVICE is a static constant of an inner class of class AdWordsService.
To access inner classes you need to use java's internal name mangling scheme **; separate the inner class from its outer class with a $ sign:
AdWordsService$V201109/CAMPAIGN_SERVICE
** the JVM doesn't actually have a notion of inner classes, so java "fakes" it by creating a standalone class AdWordsService$V201109
1.About accessing constants. Did you import AdWordsService? If not you either can access AdWordsService with fully qualified name: some.package.name.AdWordsService/V201109/CAMPAIGN_SERVICE, or import it via import macro.
2.Check examples here: http://clojuredocs.org/clojure_core/clojure.core/reify
(defn campaign-service [ ]
(reify
com.google.adwords.api.v201109.cm.CampaignServiceInterface
(get [_ selector] (some-function selector))
(mutate [_ operations] (some-function-2 operations))))
I'm trying to get documentation using the Clojure doc function, but can't get it recognized from the REPL (I'm using Emacs and SLIME). The following sequence describes what's going on (error message follows immediately after each line):
gaidica.core> (doc first)
; Evaluation aborted.
Unable to resolve symbol: doc in this context
[Thrown class java.lang.Exception]
gaidica.core> (clojure.core/doc first)
; Evaluation aborted.
No such var: clojure.core/doc
[Thrown class java.lang.Exception]
user> (clojure.core/doc first)
; Evaluation aborted.
No such var: clojure.core/doc
[Thrown class java.lang.Exception]
user> (doc first)
-------------------------
clojure.core/first
([coll])
Returns the first item in the collection. Calls seq on its
argument. If coll is nil, returns nil.
nil
user>
How do I refer to the doc function and get it recognized as a function, not a variable?
ADDENDUM, 6/22/11, 9 hours after question posted
#kotarak made the most relevant comment: "Note, that clojure.core/doc is 1.2 and earlier. clojure.repl/doc is 1.3 and later." Sure enough, the following worked:
user> (clojure.repl/doc first)
-------------------------
clojure.core/first
([coll])
Returns the first item in the collection. Calls seq on its
argument. If coll is nil, returns nil.
nil
user>
I was able to confirm that Clojure 1.3 was active:
user> *clojure-version*
{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"}
user>
But this too was confusing--my Leiningen project.clj had specified Clojure 1.2!
In my own experience, I once noticed that the SLIME-based REPL "hung onto" a Java classpath value even after I changed the contents of relevant directories. The solution then was to exit Emacs and lein swank, then re-enter both and try again. I tried the same and got the following result:
user> *clojure-version*
{:major 1, :minor 2, :incremental 0, :qualifier ""}
user>
The only conclusion I can make is that my previous REPL had been using Clojure 1.3. The project that I worked on previous to this had used a Clojure 1.3 snapshot, so I'm guessing that the REPL had "hung onto" Clojure 1.3 somehow.
Problem solved, lesson learned, etc. For bonus points, can anybody explain the reason for what happened (with Clojure 1.2 vs. 1.3)?
Thanks to all who contributed.
Couple of corrections. First, doc is a macro not a function. Also functions and macros can be stored in a var. Second, in clojure 1.3, which is likely the version you are using, doc is stored in the var clojure.repl/doc, not clojure.core/doc (as it is in 1.2). In the namespace user, doc is "used", aka there is an implicit "(use [clojure.repl :only [doc])". When you goto a new namespace, or even create one with ns, clojure.repl/doc is not automatically added, unlike it is with 'user.
To be more explicit about the questions:
Why does REPL treat clojure.core/doc as a var?
Functions, macros and values in clojure are either stored in vars or bound to a symbol such as in a let or function. clojure.core/doc is the var that holds the macro that does what doc does.
How do I refer to the doc function and get it recognized as a function, not a variable?
Like in all lisps, to do a call, whether a function or a macro, you must put the function/macro in the first position of a list.
(<fn/macro> *args)
So to call the macro doc on itself, you would do:
(doc doc)
The doc for doc shows its a macro so expanding it with macroexpand shows that is
expecting the name of a var containging a function. so the very short answer to your question would be "functions in a namespace are contained in vars".
in situations like this macroexpand-1 can be a good place to start:
(macroexpand-1 '(doc doc))
(clojure.core/print-doc (var doc))
sso-config.core> (doc doc)
-------------------------
clojure.core/doc
([name])
Macro
Prints documentation for a var or special form given its name