2026-01-25 03:58:39 +00:00
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > pathlib - Wren-CLI Manual</ title >
< link rel = "stylesheet" href = "../css/style.css" >
</ head >
< body >
< button class = "mobile-menu-toggle" > Menu</ button >
< div class = "container" >
< aside class = "sidebar" >
< div class = "sidebar-header" >
< h1 >< a href = "../index.html" > Wren-CLI</ a ></ h1 >
< div class = "version" > v0.4.0</ div >
</ div >
< nav class = "sidebar-nav" >
< div class = "section" >
< span class = "section-title" > Getting Started</ span >
< ul >
< li >< a href = "../getting-started/index.html" > Overview</ a ></ li >
< li >< a href = "../getting-started/installation.html" > Installation</ a ></ li >
< li >< a href = "../getting-started/first-script.html" > First Script</ a ></ li >
< li >< a href = "../getting-started/repl.html" > Using the REPL</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Language</ span >
< ul >
< li >< a href = "../language/index.html" > Syntax Overview</ a ></ li >
< li >< a href = "../language/classes.html" > Classes</ a ></ li >
< li >< a href = "../language/methods.html" > Methods</ a ></ li >
< li >< a href = "../language/control-flow.html" > Control Flow</ a ></ li >
< li >< a href = "../language/fibers.html" > Fibers</ a ></ li >
< li >< a href = "../language/modules.html" > Modules</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > API Reference</ span >
< ul >
< li >< a href = "index.html" > Overview</ a ></ li >
< li >< a href = "string.html" > String</ a ></ li >
< li >< a href = "number.html" > Num</ a ></ li >
< li >< a href = "argparse.html" > argparse</ a ></ li >
2026-01-25 12:09:28 +00:00
< li >< a href = "base64.html" > base64</ a ></ li >
< li >< a href = "crypto.html" > crypto</ a ></ li >
2026-01-25 03:58:39 +00:00
< li >< a href = "dataset.html" > dataset</ a ></ li >
2026-01-25 12:09:28 +00:00
< li >< a href = "datetime.html" > datetime</ a ></ li >
< li >< a href = "dns.html" > dns</ a ></ li >
< li >< a href = "env.html" > env</ a ></ li >
< li >< a href = "fswatch.html" > fswatch</ a ></ li >
< li >< a href = "html.html" > html</ a ></ li >
< li >< a href = "http.html" > http</ a ></ li >
< li >< a href = "io.html" > io</ a ></ li >
< li >< a href = "jinja.html" > jinja</ a ></ li >
< li >< a href = "json.html" > json</ a ></ li >
2026-01-25 03:58:39 +00:00
< li >< a href = "markdown.html" > markdown</ a ></ li >
2026-01-25 12:09:28 +00:00
< li >< a href = "math.html" > math</ a ></ li >
< li >< a href = "net.html" > net</ a ></ li >
< li >< a href = "os.html" > os</ a ></ li >
< li >< a href = "pathlib.html" class = "active" > pathlib</ a ></ li >
< li >< a href = "regex.html" > regex</ a ></ li >
< li >< a href = "scheduler.html" > scheduler</ a ></ li >
< li >< a href = "signal.html" > signal</ a ></ li >
< li >< a href = "sqlite.html" > sqlite</ a ></ li >
< li >< a href = "subprocess.html" > subprocess</ a ></ li >
< li >< a href = "sysinfo.html" > sysinfo</ a ></ li >
< li >< a href = "tempfile.html" > tempfile</ a ></ li >
< li >< a href = "timer.html" > timer</ a ></ li >
< li >< a href = "tls.html" > tls</ a ></ li >
< li >< a href = "udp.html" > udp</ a ></ li >
< li >< a href = "uuid.html" > uuid</ a ></ li >
< li >< a href = "wdantic.html" > wdantic</ a ></ li >
2026-01-25 03:58:39 +00:00
< li >< a href = "web.html" > web</ a ></ li >
2026-01-25 12:09:28 +00:00
< li >< a href = "websocket.html" > websocket</ a ></ li >
2026-01-25 03:58:39 +00:00
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Tutorials</ span >
< ul >
< li >< a href = "../tutorials/index.html" > Tutorial List</ a ></ li >
< li >< a href = "../tutorials/http-client.html" > HTTP Client</ a ></ li >
< li >< a href = "../tutorials/websocket-chat.html" > WebSocket Chat</ a ></ li >
< li >< a href = "../tutorials/database-app.html" > Database App</ a ></ li >
< li >< a href = "../tutorials/template-rendering.html" > Templates</ a ></ li >
< li >< a href = "../tutorials/cli-tool.html" > CLI Tool</ a ></ li >
2026-01-25 18:02:02 +00:00
< li >< a href = "../tutorials/web-server.html" > Web Server</ a ></ li >
2026-01-25 03:58:39 +00:00
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > How-To Guides</ span >
< ul >
< li >< a href = "../howto/index.html" > How-To List</ a ></ li >
< li >< a href = "../howto/http-requests.html" > HTTP Requests</ a ></ li >
< li >< a href = "../howto/json-parsing.html" > JSON Parsing</ a ></ li >
< li >< a href = "../howto/regex-patterns.html" > Regex Patterns</ a ></ li >
< li >< a href = "../howto/file-operations.html" > File Operations</ a ></ li >
< li >< a href = "../howto/async-operations.html" > Async Operations</ a ></ li >
< li >< a href = "../howto/error-handling.html" > Error Handling</ a ></ li >
</ ul >
</ div >
2026-01-25 18:02:02 +00:00
< div class = "section" >
< span class = "section-title" > Contributing</ span >
< ul >
< li >< a href = "../contributing/index.html" > Overview</ a ></ li >
< li >< a href = "../contributing/module-overview.html" > Module Architecture</ a ></ li >
< li >< a href = "../contributing/pure-wren-module.html" > Pure-Wren Modules</ a ></ li >
< li >< a href = "../contributing/c-backed-module.html" > C-Backed Modules</ a ></ li >
< li >< a href = "../contributing/foreign-classes.html" > Foreign Classes</ a ></ li >
< li >< a href = "../contributing/async-patterns.html" > Async Patterns</ a ></ li >
< li >< a href = "../contributing/testing.html" > Writing Tests</ a ></ li >
< li >< a href = "../contributing/documentation.html" > Documentation</ a ></ li >
</ ul >
</ div >
2026-01-25 03:58:39 +00:00
</ nav >
</ aside >
< main class = "content" >
< nav class = "breadcrumb" >
< a href = "../index.html" > Home</ a >
< span class = "separator" > /</ span >
< a href = "index.html" > API Reference</ a >
< span class = "separator" > /</ span >
< span > pathlib</ span >
</ nav >
< article >
< h1 > pathlib</ h1 >
< p > The < code > pathlib</ code > module provides object-oriented filesystem path operations. Inspired by Python's < code > pathlib</ code > , it offers immutable < code > Path</ code > objects that combine path manipulation with filesystem I/O in a single interface.</ p >
< pre >< code > import "pathlib" for Path</ code ></ pre >
< div class = "toc" >
< h4 > On This Page</ h4 >
< ul >
< li >< a href = "#purepath-class" > PurePath Class</ a ></ li >
< li >< a href = "#path-class" > Path Class</ a ></ li >
< li >< a href = "#path-properties" > Path Properties</ a ></ li >
< li >< a href = "#path-manipulation" > Path Manipulation</ a ></ li >
< li >< a href = "#filesystem-operations" > Filesystem Operations</ a ></ li >
< li >< a href = "#directory-operations" > Directory Operations</ a ></ li >
< li >< a href = "#symlink-operations" > Symlink Operations</ a ></ li >
< li >< a href = "#examples" > Examples</ a ></ li >
</ ul >
</ div >
< h2 id = "purepath-class" > PurePath Class</ h2 >
< div class = "class-header" >
< h3 > PurePath</ h3 >
< p > String-only path operations without filesystem access. Base class for < code > Path</ code > .</ p >
</ div >
< h3 > Constructor</ h3 >
< div class = "method-signature" >
< span class = "method-name" > PurePath.new</ span > (< span class = "param" > path</ span > ) → < span class = "type" > PurePath</ span >
</ div >
< p > Creates a new PurePath from a string or another PurePath.</ p >
< pre >< code > var p = PurePath.new("/home/user/file.txt")</ code ></ pre >
< h3 > Properties</ h3 >
< div class = "method-signature" >
< span class = "method-name" > parts</ span > → < span class = "type" > List</ span >
</ div >
< p > The individual components of the path.</ p >
< pre >< code > var p = Path.new("/home/user/file.txt")
System.print(p.parts) // [/, home, user, file.txt]</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > name</ span > → < span class = "type" > String</ span >
</ div >
< p > The final component of the path (filename with extension).</ p >
< pre >< code > var p = Path.new("/home/user/file.tar.gz")
System.print(p.name) // file.tar.gz</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > stem</ span > → < span class = "type" > String</ span >
</ div >
< p > The filename without the last extension.</ p >
< pre >< code > var p = Path.new("/home/user/file.tar.gz")
System.print(p.stem) // file.tar</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > suffix</ span > → < span class = "type" > String</ span >
</ div >
< p > The last file extension, including the leading dot.</ p >
< pre >< code > var p = Path.new("/home/user/file.tar.gz")
System.print(p.suffix) // .gz</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > suffixes</ span > → < span class = "type" > List</ span >
</ div >
< p > All file extensions as a list.</ p >
< pre >< code > var p = Path.new("/home/user/file.tar.gz")
System.print(p.suffixes) // [.tar, .gz]</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > parent</ span > → < span class = "type" > Path</ span >
</ div >
< p > The logical parent of the path.</ p >
< pre >< code > var p = Path.new("/home/user/file.txt")
System.print(p.parent) // /home/user</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > parents</ span > → < span class = "type" > List</ span >
</ div >
< p > A list of all ancestor paths, from immediate parent to root.</ p >
< pre >< code > var p = Path.new("/home/user/docs/file.txt")
for (ancestor in p.parents) {
System.print(ancestor)
}
// /home/user/docs
// /home/user
// /home
// /</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > drive</ span > → < span class = "type" > String</ span >
</ div >
< p > The drive letter (Windows only). Returns empty string on POSIX.</ p >
< div class = "method-signature" >
< span class = "method-name" > root</ span > → < span class = "type" > String</ span >
</ div >
< p > The root of the path. Returns < code > "/"</ code > for absolute paths, empty string for relative.</ p >
< div class = "method-signature" >
< span class = "method-name" > anchor</ span > → < span class = "type" > String</ span >
</ div >
< p > The concatenation of drive and root.</ p >
< div class = "method-signature" >
< span class = "method-name" > isAbsolute</ span > → < span class = "type" > Bool</ span >
</ div >
< p > True if the path is absolute (has a root).</ p >
< pre >< code > System.print(Path.new("/etc/hosts").isAbsolute) // true
System.print(Path.new("relative/path").isAbsolute) // false</ code ></ pre >
< h2 id = "path-manipulation" > Path Manipulation</ h2 >
< div class = "method-signature" >
< span class = "method-name" > path</ span > / < span class = "param" > other</ span > → < span class = "type" > Path</ span >
</ div >
< p > Joins two paths using the < code > /</ code > operator. If < code > other</ code > is absolute, it replaces the current path.</ p >
< pre >< code > var base = Path.new("/home/user")
var full = base / "documents" / "file.txt"
System.print(full) // /home/user/documents/file.txt</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > joinpath</ span > (< span class = "param" > other</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Joins paths. Accepts a string, Path, or List of components.</ p >
< pre >< code > var p = Path.new("/home").joinpath("user").joinpath("file.txt")
System.print(p) // /home/user/file.txt
var q = Path.new("/home").joinpath(["user", "docs", "file.txt"])
System.print(q) // /home/user/docs/file.txt</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > withName</ span > (< span class = "param" > newName</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Returns a new path with the filename replaced.</ p >
< pre >< code > var p = Path.new("/home/user/old.txt")
System.print(p.withName("new.txt")) // /home/user/new.txt</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > withStem</ span > (< span class = "param" > newStem</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Returns a new path with the stem replaced, keeping the extension.</ p >
< pre >< code > var p = Path.new("/data/archive.tar.gz")
System.print(p.withStem("backup")) // /data/backup.gz</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > withSuffix</ span > (< span class = "param" > newSuffix</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Returns a new path with the extension replaced.</ p >
< pre >< code > var p = Path.new("/data/file.txt")
System.print(p.withSuffix(".md")) // /data/file.md</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > relativeTo</ span > (< span class = "param" > base</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Returns a relative path from < code > base</ code > to this path. Aborts if the path is not relative to < code > base</ code > .</ p >
< pre >< code > var p = Path.new("/home/user/docs/file.txt")
System.print(p.relativeTo("/home/user")) // docs/file.txt</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > match</ span > (< span class = "param" > pattern</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Matches the filename against a glob pattern. Supports < code > *</ code > and < code > ?</ code > wildcards.</ p >
< pre >< code > var p = Path.new("/home/user/notes.txt")
System.print(p.match("*.txt")) // true
System.print(p.match("*.md")) // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > asPosix</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the path string with forward slashes (converts backslashes on Windows).</ p >
< div class = "method-signature" >
< span class = "method-name" > expanduser</ span > () → < span class = "type" > Path</ span >
</ div >
< p > Expands a leading < code > ~</ code > to the user's home directory.</ p >
< pre >< code > var p = Path.new("~/.config/app")
System.print(p.expanduser()) // /home/alice/.config/app</ code ></ pre >
< h3 > Operators</ h3 >
< div class = "method-signature" >
< span class = "method-name" > ==</ span > (< span class = "param" > other</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Compares two paths for equality by their string representation.</ p >
< div class = "method-signature" >
< span class = "method-name" > !=</ span > (< span class = "param" > other</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Compares two paths for inequality.</ p >
< div class = "method-signature" >
< span class = "method-name" > toString</ span > → < span class = "type" > String</ span >
</ div >
< p > Returns the path as a string.</ p >
< h2 id = "path-class" > Path Class</ h2 >
< div class = "class-header" >
< h3 > Path</ h3 >
< p > Extends PurePath with filesystem operations. This is the primary class for working with paths.</ p >
</ div >
< h3 > Constructor</ h3 >
< div class = "method-signature" >
< span class = "method-name" > Path.new</ span > (< span class = "param" > path</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Creates a new Path from a string or another Path.</ p >
< pre >< code > var p = Path.new("/home/user/file.txt")</ code ></ pre >
< h3 > Class Properties</ h3 >
< div class = "method-signature" >
< span class = "method-name" > Path.cwd</ span > → < span class = "type" > Path</ span >
</ div >
< p > The current working directory as a Path.</ p >
< pre >< code > System.print(Path.cwd) // /home/user/projects</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Path.home</ span > → < span class = "type" > Path</ span >
</ div >
< p > The current user's home directory as a Path.</ p >
< pre >< code > System.print(Path.home) // /home/alice</ code ></ pre >
< h2 id = "filesystem-operations" > Filesystem Operations</ h2 >
< div class = "method-signature" >
< span class = "method-name" > exists</ span > () → < span class = "type" > Bool</ span >
</ div >
< p > Returns true if the path points to an existing file or directory.</ p >
< pre >< code > if (Path.new("/etc/hosts").exists()) {
System.print("File exists")
}</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isFile</ span > () → < span class = "type" > Bool</ span >
</ div >
< p > Returns true if the path points to a regular file.</ p >
< div class = "method-signature" >
< span class = "method-name" > isDir</ span > () → < span class = "type" > Bool</ span >
</ div >
< p > Returns true if the path points to a directory.</ p >
< div class = "method-signature" >
< span class = "method-name" > isSymlink</ span > () → < span class = "type" > Bool</ span >
</ div >
< p > Returns true if the path is a symbolic link.</ p >
< div class = "method-signature" >
< span class = "method-name" > stat</ span > () → < span class = "type" > Stat</ span >
</ div >
< p > Returns a Stat object with file metadata (size, mode, timestamps).</ p >
< pre >< code > var s = Path.new("/etc/hosts").stat()
System.print(s.size) // 234</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > lstat</ span > () → < span class = "type" > Stat</ span >
</ div >
< p > Like < code > stat()</ code > but does not follow symbolic links.</ p >
< div class = "method-signature" >
< span class = "method-name" > readText</ span > () → < span class = "type" > String</ span >
</ div >
< p > Reads the entire file contents as a string.</ p >
< pre >< code > var content = Path.new("config.json").readText()
System.print(content)</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > readBytes</ span > () → < span class = "type" > String</ span >
</ div >
< p > Reads the entire file contents as bytes.</ p >
< div class = "method-signature" >
< span class = "method-name" > writeText</ span > (< span class = "param" > content</ span > )
</ div >
< p > Writes a string to the file, creating or overwriting it.</ p >
< pre >< code > Path.new("output.txt").writeText("Hello, World!")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > writeBytes</ span > (< span class = "param" > content</ span > )
</ div >
< p > Writes bytes to the file, creating or overwriting it.</ p >
< div class = "method-signature" >
< span class = "method-name" > touch</ span > ()
</ div >
< p > Creates an empty file if it does not exist, or updates its modification time if it does.</ p >
< pre >< code > Path.new("marker.txt").touch()</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > unlink</ span > ()
</ div >
< p > Deletes the file.</ p >
< div class = "method-signature" >
< span class = "method-name" > rename</ span > (< span class = "param" > target</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Moves or renames the file to < code > target</ code > . Returns the new Path.</ p >
< pre >< code > var old = Path.new("draft.txt")
var published = old.rename("article.txt")
System.print(published) // article.txt</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > replace</ span > (< span class = "param" > target</ span > ) → < span class = "type" > Path</ span >
</ div >
< p > Alias for < code > rename()</ code > . Replaces the target if it exists.</ p >
< div class = "method-signature" >
< span class = "method-name" > copyfile</ span > (< span class = "param" > dest</ span > )
</ div >
< p > Copies this file to < code > dest</ code > .</ p >
< pre >< code > Path.new("original.txt").copyfile("backup.txt")</ code ></ pre >
2026-01-25 12:09:28 +00:00
< div class = "method-signature" >
< span class = "method-name" > size</ span > () → < span class = "type" > Num</ span >
</ div >
< p > Returns the size of the file in bytes.</ p >
< pre >< code > var bytes = Path.new("data.txt").size()
System.print("File size: %(bytes) bytes")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > mtime</ span > () → < span class = "type" > Num</ span >
</ div >
< p > Returns the modification time as a Unix timestamp (seconds since epoch).</ p >
< pre >< code > var modified = Path.new("file.txt").mtime()
System.print("Last modified: %(modified)")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > atime</ span > () → < span class = "type" > Num</ span >
</ div >
< p > Returns the access time as a Unix timestamp.</ p >
< div class = "method-signature" >
< span class = "method-name" > ctime</ span > () → < span class = "type" > Num</ span >
</ div >
< p > Returns the change time (inode change) as a Unix timestamp.</ p >
2026-01-25 03:58:39 +00:00
< div class = "method-signature" >
< span class = "method-name" > chmod</ span > (< span class = "param" > mode</ span > )
</ div >
< p > Changes the file permissions. Mode is an octal number.</ p >
< pre >< code > Path.new("script.sh").chmod(0x1ed) // 0755 in octal</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > resolve</ span > () → < span class = "type" > Path</ span >
</ div >
< p > Returns the absolute real path, resolving any symlinks.</ p >
< pre >< code > var real = Path.new("./relative/../file.txt").resolve()
System.print(real) // /home/user/file.txt</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > samefile</ span > (< span class = "param" > other</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Returns true if this path and < code > other</ code > refer to the same file (compares inodes).</ p >
< div class = "method-signature" >
< span class = "method-name" > owner</ span > () → < span class = "type" > String</ span >
</ div >
< p > Returns the username of the file owner (POSIX only).</ p >
< div class = "method-signature" >
< span class = "method-name" > group</ span > () → < span class = "type" > String</ span >
</ div >
< p > Returns the group name of the file (POSIX only).</ p >
< h2 id = "directory-operations" > Directory Operations</ h2 >
< div class = "method-signature" >
< span class = "method-name" > mkdir</ span > ()
</ div >
< p > Creates the directory.</ p >
< div class = "method-signature" >
< span class = "method-name" > mkdir</ span > (< span class = "param" > parents</ span > )
</ div >
< p > Creates the directory. If < code > parents</ code > is true, creates all intermediate directories.</ p >
< pre >< code > Path.new("/tmp/a/b/c").mkdir(true)</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > rmdir</ span > ()
</ div >
< p > Removes an empty directory.</ p >
< div class = "method-signature" >
< span class = "method-name" > rmtree</ span > ()
</ div >
< p > Recursively deletes the directory and all its contents.</ p >
< pre >< code > Path.new("/tmp/build_output").rmtree()</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > iterdir</ span > () → < span class = "type" > List</ span >
</ div >
< p > Returns a list of Path objects for each entry in the directory.</ p >
< pre >< code > for (entry in Path.new(".").iterdir()) {
System.print(entry.name)
}</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > glob</ span > (< span class = "param" > pattern</ span > ) → < span class = "type" > List</ span >
</ div >
< p > Returns paths matching the glob pattern in this directory. Supports < code > *</ code > and < code > ?</ code > wildcards.</ p >
< pre >< code > var txtFiles = Path.new(".").glob("*.txt")
for (f in txtFiles) {
System.print(f.name)
}</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > rglob</ span > (< span class = "param" > pattern</ span > ) → < span class = "type" > List</ span >
</ div >
< p > Recursively matches files in this directory and all subdirectories.</ p >
< pre >< code > var allWren = Path.cwd.rglob("*.wren")
System.print("Found %(allWren.count) Wren files")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > walk</ span > () → < span class = "type" > List</ span >
</ div >
< p > Recursively walks the directory tree top-down. Returns a list of < code > [dirPath, dirNames, fileNames]</ code > tuples.</ p >
< pre >< code > for (entry in Path.new("src").walk()) {
var dir = entry[0]
var dirs = entry[1]
var files = entry[2]
for (f in files) {
System.print(dir / f)
}
}</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > walk</ span > (< span class = "param" > topDown</ span > ) → < span class = "type" > List</ span >
</ div >
< p > Walks the directory tree. If < code > topDown</ code > is false, visits child directories before parents.</ p >
< h2 id = "symlink-operations" > Symlink Operations</ h2 >
< div class = "method-signature" >
< span class = "method-name" > symlinkTo</ span > (< span class = "param" > target</ span > )
</ div >
< p > Creates a symbolic link at this path pointing to < code > target</ code > .</ p >
< pre >< code > Path.new("/tmp/link").symlinkTo("/etc/hosts")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > hardlinkTo</ span > (< span class = "param" > target</ span > )
</ div >
< p > Creates a hard link at this path pointing to < code > target</ code > .</ p >
< div class = "method-signature" >
< span class = "method-name" > readlink</ span > () → < span class = "type" > String</ span >
</ div >
< p > Returns the target of the symbolic link.</ p >
< h2 id = "examples" > Examples</ h2 >
< h3 > Configuration File Management</ h3 >
< pre >< code > import "pathlib" for Path
import "json" for Json
var configDir = Path.home / ".config" / "myapp"
if (!configDir.exists()) {
configDir.mkdir(true)
}
var configFile = configDir / "settings.json"
if (!configFile.exists()) {
configFile.writeText(Json.stringify({
"theme": "dark",
"language": "en"
}, 2))
}
var settings = Json.parse(configFile.readText())
System.print("Theme: %(settings["theme"])")</ code ></ pre >
< h3 > Batch File Processing</ h3 >
< pre >< code > import "pathlib" for Path
var dataDir = Path.new("./data")
for (file in dataDir.glob("*.csv")) {
var size = file.stat().size
System.print("%(file.name): %(size) bytes")
}
var total = 0
for (wren in Path.cwd.rglob("*.wren")) {
total = total + 1
}
System.print("Found %(total) Wren source files")</ code ></ pre >
< h3 > Directory Tree Traversal</ h3 >
< pre >< code > import "pathlib" for Path
var src = Path.new("src")
for (entry in src.walk()) {
var dir = entry[0]
var files = entry[2]
if (files.count > 0) {
System.print("%(dir.relativeTo(src)):")
for (f in files) {
System.print(" %(f)")
}
}
}</ code ></ pre >
< h3 > Path Manipulation</ h3 >
< pre >< code > import "pathlib" for Path
var p = Path.new("/home/user/documents/report.tar.gz")
System.print(p.name) // report.tar.gz
System.print(p.stem) // report.tar
System.print(p.suffix) // .gz
System.print(p.suffixes) // [.tar, .gz]
System.print(p.parent) // /home/user/documents
var backup = p.withSuffix(".bak")
System.print(backup) // /home/user/documents/report.tar.bak
var renamed = p.withName("summary.pdf")
System.print(renamed) // /home/user/documents/summary.pdf</ code ></ pre >
< h3 > Temporary File Cleanup</ h3 >
< pre >< code > import "pathlib" for Path
var tmpDir = Path.new("/tmp/build_artifacts")
if (tmpDir.exists()) {
tmpDir.rmtree()
}
tmpDir.mkdir(true)
(tmpDir / "output.o").touch()
(tmpDir / "output.bin").touch()
var count = tmpDir.iterdir().count
System.print("%(count) files in build directory")
tmpDir.rmtree()</ code ></ pre >
< h3 > Home Directory Expansion</ h3 >
< pre >< code > import "pathlib" for Path
var shortcuts = [
Path.new("~/.bashrc"),
Path.new("~/.config"),
Path.new("~/Documents")
]
for (p in shortcuts) {
var expanded = p.expanduser()
System.print("%(p) -> %(expanded) (exists: %(expanded.exists()))")
}</ code ></ pre >
< div class = "admonition note" >
< div class = "admonition-title" > Note</ div >
< p > Path objects are immutable. Methods like < code > withName()</ code > , < code > withSuffix()</ code > , and < code > joinpath()</ code > return new Path objects rather than modifying the original.</ p >
</ div >
< div class = "admonition tip" >
< div class = "admonition-title" > Tip</ div >
< p > Use the < code > /</ code > operator for readable path construction: < code > Path.home / ".config" / "myapp" / "settings.json"</ code > reads naturally and handles separator insertion automatically.</ p >
</ div >
</ article >
< footer class = "page-footer" >
< a href = "io.html" class = "prev" > io</ a >
< a href = "scheduler.html" class = "next" > scheduler</ a >
</ footer >
</ main >
</ div >
< script src = "../js/main.js" ></ script >
</ body >
</ html >