Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Clojure equivalent of __FILE__ (found in Ruby & Perl)

Tags:

clojure

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)

like image 922
jshen Avatar asked Oct 20 '10 23:10

jshen


4 Answers

*file*

API Reference (add *file* to the url)

like image 86
Martin Broadhurst Avatar answered Nov 19 '22 03:11

Martin Broadhurst


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/

like image 23
draegtun Avatar answered Nov 19 '22 04:11

draegtun


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)
like image 43
cldwalker Avatar answered Nov 19 '22 04:11

cldwalker


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

like image 1
boxed Avatar answered Nov 19 '22 04:11

boxed