Changing Cake's current directory - clojure

Is it possible to configure Cake such that, if test.clj looks like this:
(use 'java.io.File)
(println (.getAbsolutePath (File. ".")))
running cake run test.clj will print the current directory, not /home/retief/.cake/. ?
Running clojure test.clj works properly, with my custom (and very simple) clojure script, but this requires me to start a new jvm every time. Being able to use cake to avoid this and keep my current directory would be useful.
I recognize that using cake within an actual clojure project sets the current directory to the project root, but I am trying to find something that would work for more general scripting tasks.

Cake's persistent JVM doesn't see what directory the client-cake-process is in at the time of your call because the JVM is already running. It will likely be simpler to design your scripts to take the path as an argument.
ps: Cake and leiningen are merging anyway.

Related

What is the easiest way to load a clojure library all the time?

A question from an utter newcomer to clojure: What if I want to be able to start a clojure REPL from anywhere, for example because I just want to compute an exponent? How can I set up my system to do this? (I've deleted earlier links to not-quite-answers because they were cluttering up the question.) The Pomegranate documentation linked by #Jared314's answer below helped me see that I can do this:
~$ lein repl
...
user=> (use '[cemerick.pomegranate :only (add-dependencies)])
nil
user=> (add-dependencies :coordinates '[[org.clojure/math.numeric-tower "0.0.2"]])
{[org.clojure/clojure "1.3.0"] nil, [org.clojure/math.numeric-tower "0.0.2"] #{[org.clojure/clojure "1.3.0"]}}
user=> (use 'clojure.math.numeric-tower)
nil
user=> (expt 2 3)
8
Yay!
Now how can I make this happen every time I start the REPL, no matter what subdirectory I'm in?
I think I'm just ignorant of basic clojure setup. Sorry about that.
Second major edit:
I've figured out that if I use raw clojure without lein, I can execute commands on startup of the repl. For example, if the file .clojurerc contains the text (print "Yow!\n"), I can do this:
~$ java -cp /usr/local/lib/clojure-1.5.1/clojure-1.5.1.jar clojure.main -i .clojurerc -r
Clojure 1.5.1
Yow!
user=>
Can I do something like this with lein? Or maybe better yet, load clojure.math.numeric-tower automatically in clojure without using lein (since for simple command line experimentation, lein's startup is slower than starting clojure directly).
(It may seem as if I'm not trying to solve this on my own, but I that's not so. I have been doing web searches and experimenting, but I keep hitting brick walls. I'm starting to feel as if clojure is only intended for full-blown programming projects. I had assumed that it could be good for add-hoc experiments and calculations (as lisps traditionally are but Java is not). I'm not trying to incite arguments. I'm just frustrated. There ought to be a simple, well-known formula for doing what I'm trying to do.)
When you want external dependencies you will need either a new project, lein new testproject1, the lein-oneoff plugin, Pomegranate, a Leiningen profile :dependencies entry, or some specific IDE feature. (I know at least LightTable allows external dependencies in their Instarepl, so I assume you can do it in Emacs and CCW.)
It might be best to start with creating a new test project so you can see the project.clj layout. But, if you just want a one-off library in a repl, take a look at the instructions for Pomegranate's add-classpath command. Pomegranate is accessible by default in the lein repl, so their example should work without anything extra.
Edit:
From your updated question, it sounds like you want a persistent repl dependency. You can add [org.clojure/math.numeric-tower "0.0.2"] to your ~/.lein/profiles.clj profile file, under the :repl profile.
{:user {}
:repl {:dependencies [[org.clojure/math.numeric-tower "0.0.2"]]
:repl-options {:init (use 'clojure.math.numeric-tower)}}}
Then when you run lein repl:
(expt 2 3) ;=> 8
Looking at this question a few months later, I realized that I settled on a different solution, but never posted it. I now leave references to math.numeric-tower out of both .clojurerc and .lein/project.clj, since I don't need it for most Leiningen projects. And when I want to use Clojure for quick calculations, I start Clojure via a shell script without Leiningen to avoid slow startup. This is what's in the shell script:
#!/bin/sh
jars=/usr/local/lib/clojure-1.5.1/clojure-1.5.1.jar:/usr/local/lib/clojure-1.5.1/math.numeric-tower-0.0.2.jar
while [ "$1" != "${1%.jar}" ]; do # while param is a jar file
jars="$jars:$1"
shift
done
jars="$jars:."
exec rlwrap java -cp "$jars" clojure.main -e "(use 'clojure.math.numeric-tower)" "$#" -r
The middle part allows you to add jars on the command line, but in practice I don't find that useful, given that I use Leiningen for ongoing projects. Someone else might find that part of the script useful, though. rlwrap is a utility that gives you command line history, though it's not as good as what Leiningen provides, for my purposes.

How to extract Clojure REPL history

I have written some code within the plain console REPL of Clojure (lein repl). Now I would like to extract the history in order to get the code that I have written in there. Can I do this somehow?
Each Leiningen project stores its REPL usage history in the .lein-repl-history file. There's a global repl-history file as well, located at ~/.lein.

Can you save your Clojure REPL's state (or, effectivelly, can you program complex programs using REPL?)

After defining variables, functions, etc., can you save what you have done on the REPL too an text .clj file?
most people work with the repl through an editor such ad Eclipse/Emacs/vim and that editor has the ability to save the repl, though without some diligence on the developers part this will likely be an incomplete record of what happened. Some of the state of the repl may have come from loading files etc which will be in a different state.
So the short answer is typically not.
In Linux (mine = Ubuntu 16.04.2 LTS) if you are using lein then check for .lein (hidden directory) and look for repl-history. You should find the commands that you have typed or pasted into the REPL. This can be a source for later edit - I use geany...
I am answering the parenthetical part of your question. For me, the Clojure REPL is very useful for testing functions and proving out concepts that take no more than a few lines. I will often put hooks in a module that is not the main, just so I can load a file and run it through a couple of functions. I can also do this from main using the same mindset; that is write a debug function.
I found the Eclipse plugin to be quite useful, but I do not use it much these days, mostly Vim and running the module with one or more special functions and running the main. I don't know of any way to save REPL state.

How can you dump contents of Clojure REPL to a file?

So I have been working on a Clojure tutorial and it's pretty fun so far. Unfortunately, every time I close my REPL out, I lose all of the defn and def that I created in the previous session.
So, to save time in the future, is it possible to have the Clojure REPL save everything I've typed to a file so I can dig out what I need for future uses?
I think most people work by using their IDE to send fragments of code to the REPL, rather than doing a lot of direct hacking in the REPL. This way you have a better idea of the current state of the program.
If you use Emacs and SLIME, you can save the REPL buffer to a file just like saving any other buffer.
If you are using a Unix-like operating system you can start your REPL using rlwrap. This would give you Ctrl-R for accessing commands from history in an easy way, as well as storing the history itself.
You'd just have to install rlwrap and prepend it to the line where you start REPL, e.g. rlwrap lein repl
Couple of tips:
I do a lot of coding in the REPL, but as soon as I write something that works then I copy/paste it into a source file. Then I can just run or reload that source file whenever I want to get a REPL environment back to a fully configured state.
Some REPLs (e.g. the Eclipse Counterclockwise REPL that I use) keep history from previous sessions so you can up-arrow to the earlier REPL commands you want to repeat.
This is actually a harder problem than it seems because a dump like this must take into account symbol and vars dependencies and output to file in the correct order of symbols. That said since code is data one should be able to write a function that does that.

FileNotFoundException when making a jar file from the clojure file

I am trying to go through the process of creating a jar file from a simple clojure file. Below is my clojure code:
(ns app.first (:gen-class))
(refer 'clojure.core)
(defn -main [& args] (println "this program worked!"))
I am using these instructions to create the jar file: http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips
I see the error "java.io.FileNotFoundException: Could not locate app/hello__init.class or app/hello.clj on classpath: (NO_SOURCE_FILE:0)" when I try to complete the (compile 'app.first) step.
The only difference between my attempt and the link is the name of my file (first.clj instead of hello.clj).
Can anyone see where I am going wrong? Or for that matter, all I want to do is learn how to create a jar from a clojure file, so if anyone knows of a better/easier way to do that, let me know.
It's better to use Leiningen for such tasks - it allows to maintain dependencies, and packs all necessary components into jar file
I'm rusty on this, but I heard about other people with similar problems.
I think it's helpful to remember that the classpath you indicate points to the root of your class tree, and package names end up creating subdirectories within that tree. Awkwardly stated, but I hope you get the idea. Thus, I think you need to do some kind of gymnastics with creating directories to match the "app.first" -> "/app/first" hierarchy.
Sorry, that's as close as I come to a sensible and useful answer. Hope this helps you.
EDIT:
The Prime Directive of Computer Science: It only works if you do everything right! I spent almost 10 minutes fiddling with this but was finally successful.
Here's what I needed to do to get your program to compile:
created a directory app, and within that, first.clj with your code.
checked for the *compile-path* by doing (pr *compile-path) within Clojure. It said "classes".
created a second directory classes parallel to app.
in the shell, did export CLASSPATH=.:./classes
in Clojure, did (compile 'app.first)
... and I found a bunch of class files in classes. JARring those should be a snap.
I found it very helpful to run (doc compile) because that reminded me of the requirement to have a directory to satisfy the requirement for a *compile-path*.