Julia: Change the error behavior of Sys.which

Created on 28 May 2018  路  6Comments  路  Source: JuliaLang/julia

I have two suggestions for Sys.which, which was added in #26559:

  1. Make it both accept and return Cmds rather than Strings.

  2. Return nothing when the given command is not found rather than throwing an error. (This was actually suggested by someone else in that PR.)

As a motivation for this change, consider the case of selecting an executable from a list of candidates. With the above suggestions, one could write this

tar = coalesce(Sys.which(`tar`), Sys.which(`gtar`))

and use the value of the resulting variable directly in commands, pipeline, etc. Currently this must be written as

tar = try
    Sys.which("tar")
catch
    try
        Sys.which("gtar")
    catch
        error(":(")
    end
end

which is significantly less ergonomic.

breaking filesystem

Most helpful comment

True, though in this case the path is a path to an executable, which is likely mostly useful in Cmds, I would think.

The fact that it's a path to an executable is irrelevant. The key fact is that it's not a collection of words like a Cmd is, it's always just one path. E.g. if there's a space in the path to the executable, you have to go to extra trouble to make sure it's not split there; with a string you get the right behavior without doing anything.

All 6 comments

Definitely agree about returning nothing if a command doesn鈥檛 exist. However, I think I disagree with the part about returning a Cmd. It鈥檚 a path and the canonical representation of a path is a string; a Cmd is a kind of "vector of words". We should make sure that nothing throws an error when spliced into a Cmd though (it may already).

If sys.which("tar") returns a Cmd for the program tar, how are the arguments then specified?

how are the arguments then specified?

Interpolation

run(`$(Sys.which("tar")) xzf thingo.tar.gz`)

It鈥檚 a path and the canonical representation of a path is a string; a Cmd is a kind of vector of words.

True, though in this case the path is a path to an executable, which is likely mostly useful in Cmds, I would think.

Oops, nothing does not throw an error when spliced into a command:

julia> `$nothing`
`nothing`

That should certainly be fixed since it is unlikely that running a command called nothing is what is intended; it's a bit ad hoc but I think it's the right thing to do here.

True, though in this case the path is a path to an executable, which is likely mostly useful in Cmds, I would think.

The fact that it's a path to an executable is irrelevant. The key fact is that it's not a collection of words like a Cmd is, it's always just one path. E.g. if there's a space in the path to the executable, you have to go to extra trouble to make sure it's not split there; with a string you get the right behavior without doing anything.

There seems to be broad agreement on what to do, so de-triaging. Whether this can make it into master before the release can be discussed in #27298.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tkoolen picture tkoolen  路  3Comments

felixrehren picture felixrehren  路  3Comments

helgee picture helgee  路  3Comments

Keno picture Keno  路  3Comments

TotalVerb picture TotalVerb  路  3Comments