Accuracy of *file*

41 views
Skip to first unread message

Phil Hagelberg

unread,
Mar 11, 2009, 7:25:28 PM3/11/09
to clo...@googlegroups.com

I'm interested in getting the location on disk of the current file. It
appears *file* provides this, but unfortunately it doesn't provide an
absolute path.

Inside the file /home/phil/src/mire/src/mire/rooms.clj:

mire/rooms.clj

I tried using java.io.File so I'd have access to getAbsolutePath, but
this is inaccurate:

(.getAbsoluteFile (java.io.File. *file*)) =>
/home/phil/src/mire/mire/rooms.clj

There should be a "src" directory in between "mire" and "mire".

It looks like the value of *file* is relative to the classpath entry
where the file was loaded from, but getAbsoluteFile is assuming it's
relative to the current directory.

How do you get the absolute path for the current file?

-Phil

Paul Stadig

unread,
Mar 12, 2009, 7:05:33 AM3/12/09
to clo...@googlegroups.com
I wrote these a while ago, and I'm not sure if they're still useful or not, but I'll just send them along without any guarantee. I have used them like (__FILE__) and (__DIR__) when I wanted to get access to things relative to the current file.

(defmacro __FILE__ []
  `(if *file*
       (let [f# (ClassLoader/getSystemResource *file*)]
         (if f#
           (.getCanonicalPath (java.io.File. (.toURI f#)))
           (.getCanonicalPath (java.io.File. *file*))))))

(defmacro __DIR__ []
  `(dirname (__FILE__)))

(defn dirname [path]
  (.getParent (File. path)))



Paul

Phil Hagelberg

unread,
Mar 12, 2009, 12:50:07 PM3/12/09
to clo...@googlegroups.com
Paul Stadig <pa...@stadig.name> writes:

> I wrote these a while ago, and I'm not sure if they're still useful or not, but I'll just send them along without any guarantee. I
> have used them like (__FILE__) and (__DIR__) when I wanted to get access to things relative to the current file.
>
> (defmacro __FILE__ []
>   `(if *file*
>        (let [f# (ClassLoader/getSystemResource *file*)]
>          (if f#
>            (.getCanonicalPath (java.io.File. (.toURI f#)))
>            (.getCanonicalPath (java.io.File. *file*))))))

Wow, that's quite a set of hoops to jump through.

I don't think I could have figured that out on my own; thanks!

-Phil

Paul Stadig

unread,
Mar 12, 2009, 2:09:08 PM3/12/09
to clo...@googlegroups.com

Like I said, I wrote these a while ago when I was learning Clojure for a project that I haven't touched in a while. I'm not sure this is the best way (or even the correct way!) to do this. As I recall, I was having a problem, because *file* was only available while compiling and was nil at runtime. I ended up using these macros with defvar from clojure-contrib to find my path and bind it once during loading, like so:

(defvar *downloads* (join (__DIR__) "cache" "downloads")
  "The root path for the download cache")

Not sure if all of those assumptions are still valid, but if it helps someone, then there it is.


Paul

Reply all
Reply to author
Forward
0 new messages