How does julia know what path separator and root directory to use? - julia

Functions like joinpath use the appropriate OS-dependent separator when joining two paths (ie / on Linux, \\ on Windows, etc). How do these functions know what separator to use?
Similarly, the root directory on Linux is /, but on Windows is probably C:\\. Is there a way to retrieve the OS-dependent root directory in Julia?
Note, I've had a look at the joinpath source on github, and it appears to use an undocumented function pathsep(a,b) and a global variable path_separator_re, but I can't see how either of these work.

It uses the Sys.isunix and Sys.iswindows functions in order to conditionally define the correct path_separator_re variables, etc.
https://github.com/JuliaLang/julia/blob/5c3f58039525972b24930f356821af8299f70a26/base/path.jl#L19-L41
if Sys.isunix()
# ...
const path_separator_re = r"/+"
# ...
splitdrive(path::String) = ("",path)
elseif Sys.iswindows()
# ...
const path_separator_re = r"[/\\]+"
# ...
function splitdrive(path::String)
m = match(r"^([^\\]+:|\\\\[^\\]+\\[^\\]+|\\\\\?\\UNC\\[^\\]+\\[^\\]+|\\\\\?\\[^\\]+:|)(.*)$", path)
String(m.captures[1]), String(m.captures[2])
end
else
error("path primitives for this OS need to be defined")
end
For the root directory, check out the homedir function, which uses libuv to determine it.
https://github.com/JuliaLang/julia/blob/5c3f58039525972b24930f356821af8299f70a26/base/path.jl#L52-L77
help?> homedir
search: homedir
homedir() -> AbstractString
Return the current user's home directory.
| Note
|
| homedir determines the home directory via libuv's uv_os_homedir. For details (for example on how to specify the home
| directory via environment variables), see the uv_os_homedir documentation.

Related

Return one folder above current directory in Julia

In Julia, I can get the current directory from
#__DIR__
For example, when I run the above in the "Current" folder, it gives me
"/Users/jtheath/Dropbox/Research/Projects/Coding/Current"
However, I want it to return one folder above the present folder; i.e.,
"/Users/jtheath/Dropbox/Research/Projects/Coding"
Is there an easy way to do this in a Julia script?
First, please note that #__DIR__ generally expands to the directory of the current source file (it does however return the current working directory if there are no source files involved, e.g when run from the REPL). In order to reliably get the current working directory, you should rather use pwd().
Now to your real question: I think the easiest way to get the path to the parent directory would be to simply use dirname:
julia> dirname("/Users/jtheath/Dropbox/Research/Projects/Coding/Current")
"/Users/jtheath/Dropbox/Research/Projects/Coding"
Note that AFAIU this only uses string manipulations, and does not care whether the paths involved actually exist in the filesystem (which is why the example above works on my system although I do not have the same filesystem structure as you). dirname is also relatively sensitive to the presence/absence of a trailing slash (which shouldn't be a problem if you feed it something that comes directly from pwd() or #__DIR__).
I sometimes also use something like this, in the hope that it might be more robust when I want to work with paths that actually exist in the filesystem:
julia> curdir = pwd()
"/home/francois"
julia> abspath(joinpath(curdir, ".."))
"/home/"

Clean3.0 get directory contents

I am using Cleanide for Clean3.0 programming language.
What I am trying to do is to implement a function that receive name of a directory in my system, and return a list of all the files in that directory.
I don't know if the defintion of such function needs to be like File -> [string] or maybe something else, even that directory is a file maybe this is not the developers of Clean meant...
Thank a lot!
This functionality is not available in the StdEnv environment, but there are two libraries that can help with this:
The Directory library contains a module Directory which has a function getDirectoryContents :: !Path !*env -> (!(!DirError, [DirEntry]), !*env) | FileSystem env.
The Platform library contains a module System.Directory which has a function readDirectory :: !FilePath !*w -> (!MaybeOSError [FilePath], !*w).
In both cases the first argument is a path to the directory and the second argument is the *World, which is the typical way of Clean to perform impure operations (see chapter 9 of the language report).
Code examples
With Directory:
import Directory
Start w
# (dir,w) = getDirectoryContents (RelativePath []) w
= dir
With Platform:
import System.Directory
Start w
# (dir,w) = readDirectory "." w
= dir

R test if a file exists, and is not a directory

I have an R script that takes a file as input, and I want a general way to know whether the input is a file that exists, and is not a directory.
In Python you would do it this way: How do I check whether a file exists using Python?, but I was struggling to find anything similar in R.
What I'd like is something like below, assuming that the file.txt actually exists:
input.good = "~/directory/file.txt"
input.bad = "~/directory/"
is.file(input.good) # should return TRUE
is.file(input.bad) #should return FALSE
R has something called file.exists(), but this doesn't distinguish files from directories.
There is a dir.exists function in all recent versions of R.
file.exists(f) && !dir.exists(f)
The solution is to use file_test()
This gives shell-style file tests, and can distinguish files from folders.
E.g.
input.good = "~/directory/file.txt"
input.bad = "~/directory/"
file_test("-f", input.good) # returns TRUE
file_test("-f", input.bad) #returns FALSE
From the manual:
Usage
file_test(op, x, y) Arguments
op a character string specifying the test to be performed. Unary
tests (only x is used) are "-f" (existence and not being a directory),
"-d" (existence and directory) and "-x" (executable as a file or
searchable as a directory). Binary tests are "-nt" (strictly newer
than, using the modification dates) and "-ot" (strictly older than):
in both cases the test is false unless both files exist.
x, y character vectors giving file paths.
You can also use is_file(path) from the fs package.

Absolute path of the project root directory in Julia

The project root directory of a file located in PROJECT_ROOT/lib/code.jl can be accessed with this code:
root = dirname(dirname(#__FILE__))
Using dirname() twice seems pretty ugly. Is there a better way to do this? With Ruby, I would use this code:
root = File.expand_path('../', File.dirname(__FILE__))
Thanks for making me find out about:
"/"*relpath((#__FILE__)*"/../..","/")
According to ?relpath, it gives a path from the location of the second argument in the file-system, to the first argument. Is this better than the double dirname solution?
A variant of the same niceness is:
normpath(joinpath(#__FILE__,"..",".."))
Closest to Ruby equivalent might be:
realpath(dirname(#__FILE__)*"/..")
I like to use
module Foo
const PROJECT_ROOT = pkgdir(Foo)
end # module
where the definition of PROJECT_ROOT can also be replaced by
const PROJECT_ROOT = dirname(dirname(pathof(Foo)))
Or, you could use
const PROJECT_ROOT = pkdir(#__MODULE__)
I just use
const PROJECT_ROOT = #__DIR__
from inside my _init.jl file, which resides in the project root directory (next to the src directory) and gives you a canonical path.
I get my _init.jl files automatically executed when opening a Julia session from inside that directories by having
isfile("_init.jl") && include(joinpath(pwd(), "_init.jl"))
in my ~/.julia/config/startup.jl file. If you started Julia elsewhere, you have to include("_init.jl") it (or respective relative path) manually.

Call Rmath via Ctypes from Ocaml on OS X

I want to use R's mathematical functions as provided in libRmath from Ocaml. I successfully installed the library via brew tap homebrew science && brew install --with-librmath-only r. I end up with a .dylib in /usr/local/lib and a .h in /usr/local/include. Following the Ocaml ctypes tutorial, i do this in utop
#require "ctypes.foreign";;
open Ctypes;;
open Foreign;;
let test_pow = foreign "pow_di" (float #-> int #-> returning float);;
this complains that it can't find the symbol. What am I doing wrong? Do I need to open the dynamic library first? Set some environment variables? After googling, I also did this:
nm -gU /usr/local/lib/libRmath.dylib
which gives a bunch of symbols all with a leading underscore including 00000000000013ff T _R_pow_di. In the header file, pow_di is defined via some #define directive from _R_pow_di. I did try variations of the name like "R_pow_di" etc.
Edit: I tried compiling a simple C program using Rmath using Xcode. After setting the include path manually to include /usr/local/include, Xcode can find the header file Rmath.h. However, inside the header file, there is an include of R_ext/Boolean.h which does not seem to exist. This error is flagged by Xcode and compilation stops.
Noob alert: this may be totally obvious to a C programmer...
In order to use external library you still need to link. There're at least two different ways, either link using compiler, or link even more dynamically using dlopen.
For the first method use the following command (as an initial approximation):
ocamlbuild -pkg ctypes.foreign -lflags -cclib,-lRmath yourapp.native
under premise that your code is put into yourapp.ml file.
The second method is to use ctypes interface to dlopen to open the library. Using the correct types and name for the C function call, this goes like this:
let library = Dl.dlopen ~filename:"libRmath.dylib" ~flags:[]
let test_pow = foreign ~from:library "R_pow_di" (double #-> int #-> returning double)

Resources