14.1 Paths
A path value represents a filesystem path for the host operating system. A cross-platform path is a generalization of a path, and most path operations also accept cross-platform paths, but they produce specifically paths when given paths.
Paths are comparable, which means that generic operations like < and > work on paths.
annotation | |||
| |||
annotation | |||
| |||
annotation | |||
| |||
annotation | |||
| |||
annotation | |||
| |||
| |||
annotation | |||
| |||
annotation | |||
| |||
annotation | |||
| |||
annotation | |||
| |||
annotation | |||
| |||
enumeration | |||
| |||
annotation | |||
The Path.Absolute annotation only matches Paths that begin with a root directory or drive. The Path.Relative annotation only matches Paths that are relative to some base directory. The Path.DriveRelative annotation only matches Windows Paths that are relative to a drive.
The Path.Directory annotation only matches Paths that syntactically refer to a directory; see filesystem.directory_exists for checking whether a path refers to a directory on the filesystem.
The Path.Element annotation matches a path that
represents a single path element—
A Path.Dot symbols refer to an abstract directory-navigation path element. For both path conventions currently supported, the symbol #'same as a Path.Dot is equivalent to ".", and the symbol #'same as a Path.Dot is equivalent to "..".
A Path.like(expr) annotation is satisfied by a cross-platform path with the same convention as the result of expr, where the result of expr must satisfy PathString || CrossPath || Path.Dot, and a PathString or Path.Dot implies the current platform’s convention.
> p
Path("/home/rhombus/shape.txt")
> Path(p)
Path("/home/rhombus/shape.txt")
"/home/rhombus/shape.txt"
> bstr
#"/home/rhombus/shape.txt"
context parameter | |
> Path.bytes(p)
#"/home/rhombus/shape.txt"
#"/home/rhombus/shape.txt"
> Path.string(p)
"/home/rhombus/shape.txt"
"/home/rhombus/shape.txt"
method | |
|
> p.convention()
#'unix
The path and each part must be either a relative path, the symbol #'up (indicating the relative parent directory), or the symbol #'same (indicating the relative current directory). For Windows paths, if path is a drive specification (with or without a trailing slash) the first part can be a drive-relative path. For all platforms, the last part can be a filename.
The path and part arguments can be paths or cross-platform paths. The platform for the resulting path is inferred from the path and part arguments, where string arguments imply a path for the current platform. If different arguments are for different platforms, the Exn.Fail.Annot exception is thrown. If no argument implies a platform (i.e., all are #'up or #'same), the generated path is for the current platform.
Each part and path can optionally end in a directory separator. If the last part ends in a separator, it is included in the resulting path.
The Path.add procedure builds a path without checking the validity of the path or accessing the filesystem.
> Path.add(p, "shape.txt")
Path("/home/rhombus/shape.txt")
Path("/home/rhombus/shape.txt")
> p +/ "shape.txt"
Path("/home/rhombus/shape.txt")
method | ||
|
The Path.split function computes its result in time proportional to the length of path.
> Path.split(p)
[Path("/"), Path("home"), Path("rhombus"), Path("shape.txt")]
[Path("/"), Path("home"), Path("rhombus"), Path("shape.txt")]
method | |||
| |||
method | |||
| |||
| |||
method | |||
| |||
| |||
method | |||
|
The Path.directory_only function returns path without its final path element in the case that path is not syntactically a directory; if path has only a single, non-directory path element, #f is returned. If path is syntactically a directory, then path is returned unchanged (but as a path, if it was a string).
The Path.to_directory_path function converts path to one that syntactically represents a directory path if it does not already, typically by adding a path separator to the end.
> Path.name(p)
Path("shape.txt")
> Path.parent(p)
Path("/home/rhombus/")
> Path.directory_only(p)
Path("/home/rhombus/")
Path("/home/rhombus/")
Path("/home/rhombus/shape.txt/")
method | ||||||
|
> p.to_absolute_path(
).bytes()
#"/home/rhombus/shape.txt"
method | |||||
| |||||
| |||||
method | |||||
| |||||
| |||||
method | |||||
|
The Path.replace_suffix function removes the suffix from a path, if any, and then adds suffix, which can be "" or #"" to just remove a suffix from path or otherwise normally starts with Char"." or Byte#".".
The Path.add_suffix function first changes a Byte#"." in the path that starts its current prefix with sep, and then it adds the given suffix.
#".txt"
> p.replace_suffix(".rhm")
Path("/home/rhombus/shape.rhm")
> p.add_suffix(".rhm")
Path("/home/rhombus/shape_txt.rhm")
method | ||
| ||
| ||
method | ||
| ||
| ||
method | ||
The Path.simplify function performs the same cleansing, and then removes #'same path elements and syntactically resolves #'up elements where preceding elements can be removed. This simplification is purely syntactic and does not consult the filesystem; see also filesystem.simplify_path.
The Path.normal_case function has no effect on platforms that use Unix path conventions, and it case-folds a path’s string form on Windows.
> Path.cleanse("a/..//b")
Path("a/../b")
> Path.simplify("a/..//b")
Path("b")
method | |||||||
|
If more_than_root is #true, then if path and rel_to_path has only a root path element in common, then path is returned unchanged (except converted to a Path object if it is a string).
If more_than_same is #true, then if path and rel_to_path are syntactically equivalent, then path is returned unchanged.
If normal is #true, then on Windows, path elements are normalized for comparison. Otherwise, path elements are considered equivalent only when they have the same case.
If path and rel_to_path use different path conventions, the Exn.Fail.Annot exception is thrown.
> p.as_relative_to("/home")
Path("rhombus/shape.txt")
> p.as_relative_to("/home/racket")
Path("../rhombus/shape.txt")
14.1.1 Runtime Paths
import: rhombus/runtime_path | package: rhombus-lib |
An unusual property of runtime_path.def is that the body sequence is used in both a run-time context and a meta context, so it must be valid for both. The meta interpretation is used for tasks like creating a standalone executable to ensure that referenced files are accessible at run time.
> import:
rhombus/runtime_path
> runtime_path.def image_file: "file.png"