So here is my problem,
I have a file sample.clj in namespace abc.xyzin which i am calling db init method directly before doing any CRUD operation.
(db/init some-config)
When i require this namespace abc.xyz in a test namespace cdf.qpr as (:require [abc.xyz :refer :all]), db is already being initialized with some-config but i want to initialize it with some-other-config.
How can i require namespace preventing call of db/init
Without changing the code in namespace abc.xyz, in particular changing the line (db/init some-config), what you ask is not possible.
A more productive approach would be to ask "How do other people handle this situation, without having a top level expression like (db/init some-config) in their namespaces? I suspect most put calls like that not as top level expressions in their namespaces, but inside some init function for their entire application.
Related
I read online that Clojure uses the ASM library to generate JVM Bytecode, I also saw that Clojure has a REPL.
I assume each line of code executed by the REPL is compiled into a Java class using ASM and then that class is loaded to execute the code. If this is the case then each line would cause a new class file to be generated, so I'm not sure how local variables declared on one line could be shared with the lines which follow in the REPL.
Does anyone know how Clojure's REPL works? I tried reading the Clojure source code but I don't know much Clojure.
It's not "each line" that is compiled at a time, but "each form".
In the REPL, you are always in some namespace. You can change the current namespace of a REPL by using in-ns. In each namespace, there is a binding between symbols (loosely, "names") and Vars (loosely, a container that holds an immutable value). The "state" of the namespace is in the bindings of that namespace.
For example, if you evaluate the form (def a 17) in the current namespace, that will create a new (if it does not already exist) binding for the name a that points to a Var that contains the value 17. Now, you could later evaluate the form (+ a 25) in the same namespace. That will get the value of a in the namespace and add that to 25 to return 42.
The above is for symbols that are local to the namespace. These symbols are available to all forms evaluated in that namespace. (They also can be accessed from other namespaces, but I'll leave that out for now).
You might take a look at https://clojure.org/reference/evaluation if you have not already. The article at https://clojure.org/reference/vars might also be helpful.
I've had a problem, now it's gone, I know what fixed it but I have no idea why. I'm pretty new to clojure, but it seems to me that some namespace names will just not work, and I don't mean obvious ones that are already taken by another symbol.
I have a rather simple project to implement a scheduler, and it has three namespaces: schedule.core, schedule.jdate, and schedule.validation.
The validation namespace worked, but for the jdate namespace I always received errors like this:
CompilerException java.lang.Exception: No namespace: schedule.jdate,
compiling:(schedule/core.clj:1:1)
The errors varied slightly, depending on the way I was currently trying to solve the issue, but basically always meant the same: There was no namespace with that name, in one instance the error even said that there was no jdate__init (which I could believe) AND no jdate.clj, although the file was right there in the folder.
My namespace declarations and inclusions looked like this:
src/schedule/core.clj:
(ns schedule.core
(:gen-class)
(:require schedule.jdate)
(:refer schedule.jdate)
(:require schedule.validation)
(:refer schedule.validation))
src/schedule/jdate.clj:
(ns schedule.jdate
(:gen-class)
(:import java.util.Date)
(:import java.util.Calendar))
src/schedule/validation.clj:
(ns schedule.validation
(:gen-class))
As I said, the validation namespace worked without trouble.
Eventually I ran out of ideas and started to try things that couldn't possibly have any relation, among other things I renamed the jdate namespace to scheduledate. There was no change in the behavior.
Some more time later, I got to the "I'm not even trying anymore" stage, in which I renamed the jdate namespace to "murks" (a swiss word conveying the meaning of "I need a larger hammer for this to work") and... it worked.
I thought there must be something somewhere else in the code I changed inadvertantly that suddenly made it work. So I changed the name back to jdate. It stopped working immediately.
In the end, I'm somewhat confused. Could anybody here tell me a) why the first two names didn't work and the third one did, and b) by extension what names are save to use for namespaces, because I'm not looking forward to the feeling of playing minesweeper when naming them in the future.
EDIT: It seems that the problem stemmed from multiple conspiring sources. For one, the structure of my code required a two-way dependency of two namespaces. Since I was not very familiar with how Clojure works, I assumed a c-style include hierarchy, where files included later in the same tree had all the includes up to that point at their disposal. I am somewhat surprised at the nature of the received errors, but then again, I should know by now that Clojure error messages are almost indecipherable and tend to be highly misleading.
The inconsistent behavior seems to have originated from me frantically trying to reload different namespaces without closing the REPL in-between... i.e. the results of the REPL-operations did not always reflect the state of the code.
Oh well, that was a rather tedious lesson in "Clojure really hates circular includes", but I think it's one I've learned now.
I'm using vim-clojure-static, a Clojure plugin. I can add my own functions and macros to a syntax group by doing for example:
syntax keyword clojureMacro defsystem
But in Clojure, after one has required (imported) code from other namespaces, one has to namespace qualify the functions and macros. For example, if I required the namespace my-namespace and defsystem was in my-namespace, I would have to refer to it by ny-namespace/defsystem. But as one requires another namespace, one may shorten (actually rename) the namespace name, to, for example, my/defsystem.
So, the problem: the syntax keyword clojureMacro defsystem does not work if defsystem is namespace qulified, like my/defsystem. And the namespace qualifier can be anything. How can I fix that? The regex '\m[a-z.+\-*_!?]\+\/' matches namespace qualifiers. So basically I want code that matches '\m[a-z.+\-*_!?]\+\/' immediately followed by a clojureMacro, to be highlighted as if the whole thing was a clojureMacro.
It doesn't really answer your question, but anyhow.
Back in the days VimClojure provided the so-called "dynamic highlighting." It would inspect the required namespaces (and their aliases) and would dynamically add the symbols of the referenced namespaces to the highlighting. So if you typed "m/defsystem" it would by highlighted, but "m/non-existant" or "not-m/defsystem" would not. The highlighting did respect being a macro or function etc. Would you ever change the namespace alias from "m" to something else, the highlighting would (almost) automatically adapt. However it needed a backend server running.
Maybe you want to ping the guys on the vimclojure google group. It's all about vim and clojure. Maybe someone there is willing to lend a hand and carry over this functionality as a fireplace extension.
For anyone out there still looking for a solution, I've reimplemented VimClojure's dynamic highlighting feature as a fireplace.vim plugin:
https://github.com/guns/vim-clojure-highlight
I'm familiar with packages from e.g. Java and Lisp, but what I'm seeing in other people's code is some apparent idioms like calling the entry point '-main' and using a backtick for the namespace name in (in-ns `foo), that kind of thing. I don't see these spelled out anywhere in docs or tutorials. Is there some resource which explains such conventions around structuring programs?
Edit:
I think I must have picked up the backtick thing from this answer: Splitting a Clojure namespace over multiple files, which I stumbled across while trying to make sense of (defn -main ...). Given the author, I took it as best practice. However, now that I poke around in the Clojure sources he cites, I see that only the regular quote is used. I guess most likely it's a typo.
(Narrowed the scope of the question title accordingly)
The default for gen-class is to use - as the prefix for method names of that class. Which is why -main is the default entry point for java -cp clojure.jar yourclass
Backticks qualify their argument with the current namespace, so (in-ns `foo) is the same as (in-ns 'current-namespace/foo) and I don't think that's particularly idiomatic. The idiomatic way is to put each namespace in its own file with (ns ...) at the top, and use or require them as needed.
Would it be possible to override the 'require' command so that it will try to download a certain resource if it was not found on the local machine. For example:
(require 'examples.introduction)
; if not found => download from the net
; (url: http://media.pragprog.com/titles/shcloj/code/examples/introduction.clj)
You could override the require function and of course the overriden variant could download stuff if the namespace it was asked for is not available on the classpath. Overriding the way :require works in (ns ...) forms is, AFAIK, impossible for now due to the way in which ns is handled.
Note that such a 'downloading require' wouldn't be very helpful if you wanted to place new paths on the classpath (including new jars), as classpath injection doesn't work reliably in Clojure (due to JVM issues). There is clojure.core/add-classpath... but it's been marked as deprecated since forever now, its use is strongly discouraged, there are no guarantees that it will work for you and this situation isn't likely to change anytime soon. On the other hand, if you wanted to put new source files in a directory which was already present on the classpath, then that should work fine.
In case you do want to play around with overriding require, if you have a foo namespace, you could do
(ns foo
(:refer-clojure :exclude [require])
; other stuff; any :requires here will work as usual!
)
Then define your own require, using clojure.core/require when appropriate:
(defn require [ns-symbol]
(do-stuff-to-obtain-the-namespace))
clojure.contrib.find-namespaces namespace might be helpful in finding out what's available on the classpath. (Or you could use the the-ns function and see if it throws an exception after an initial attempt at requiring the namespace through clojure.core/require.)
Note that the binding approach which might come to mind first ((binding [require ...] ...)) will not work, since require normally resolves to a Var interned in the clojure.core namespace and Vars from namespaces whose names start with clojure are currently directly linked by the compiler (meaning no actual Var lookup is performed at runtime, so rebinding of those Vars has no effect on the code).
The (:refer-clojure :exclude [require]) in the ns form for your namespace prevents require from resolving to clojure.core/require and leaves you free to define a Var of that name in your own namespace. As mentioned above, that doesn't prevent the clojure.core/require Var from being accessible if you type out the fully qualified the symbol.
Actually, (add-classpath "http://foo/bar/baz/src/") or (add-classpath "http://www.foo.com/bar.jar"), will allow requiring remote stuff.
MichaĆ's warnings do apply though: Only use this for toying at the repl ...