NAME
    Path::Naive - Yet another abstract, Unix-like path manipulation routines

VERSION
    This document describes version 0.044 of Path::Naive (from Perl
    distribution Path-Naive), released on 2024-07-17.

SYNOPSIS
     use Path::Naive qw(
         abs_path
         concat_and_normalize_path
         concat_path
         is_abs_path
         is_rel_path
         normalize_and_split_path
         normalize_path
         rel_path
         split_path
    );

     # split path to its elements.
     @dirs = split_path("");              # dies, empty path
     @dirs = split_path("/");             # -> ()
     @dirs = split_path("a");             # -> ("a")
     @dirs = split_path("/a");            # -> ("a")
     @dirs = split_path("/a/");           # -> ("a")
     @dirs = split_path("/a/b/c");        # -> ("a", "b", "c")
     @dirs = split_path("/a//b////c//");  # -> ("a", "b", "c")
     @dirs = split_path("../a");          # -> ("..", "a")
     @dirs = split_path("./a");           # -> (".", "a")
     @dirs = split_path("../../a");       # -> ("..", "..", "a")
     @dirs = split_path(".././../a");     # -> ("..", ".", "..", "a")
     @dirs = split_path("a/b/c/..");      # -> ("a", "b", "c", "..")

     # normalize path (collapse . & .., remove double & trailing / except on "/").
     $p = normalize_path("");              # dies, empty path
     $p = normalize_path("/");             # -> "/"
     $p = normalize_path("..");            # -> ".."
     $p = normalize_path("./");            # -> "."
     $p = normalize_path("//");            # -> "/"
     $p = normalize_path("a/b/.");         # -> "a/b"
     $p = normalize_path("a/b/./");        # -> "a/b"
     $p = normalize_path("a/b/..");        # -> "a"
     $p = normalize_path("a/b/../");       # -> "a"
     $p = normalize_path("/a/./../b");     # -> "/b"
     $p = normalize_path("/a/../../b");    # -> "/b" (.. after hitting root is ok)

     # check whether path is absolute (starts from root).
     say is_abs_path("/");                # -> 1
     say is_abs_path("/a");               # -> 1
     say is_abs_path("/..");              # -> 1
     say is_abs_path(".");                # -> 0
     say is_abs_path("./b");              # -> 0
     say is_abs_path("b/c/");             # -> 0

     # this is basically just !is_abs_path($path).
     say is_rel_path("/");                # -> 0
     say is_rel_path("a/b");              # -> 1

     # concatenate two paths.
     say concat_path("a", "b");           # -> "a/b"
     say concat_path("a/", "b");          # -> "a/b"
     say concat_path("a", "b/");          # -> "a/b/"
     say concat_path("a", "../b/");       # -> "a/../b/"
     say concat_path("a/b", ".././c");    # -> "a/b/.././c"
     say concat_path("../", ".././c/");   # -> "../.././c/"
     say concat_path("a/b/c", "/d/e");    # -> "/d/e" (path2 is absolute)

     # this is just concat_path + normalize_path the result. note that it can return
     # path string (in scalar context) or path elements (in list context).
     $p = concat_and_normalize_path("a", "b");         # -> "a/b"
     $p = concat_and_normalize_path("a/", "b");        # -> "a/b"
     $p = concat_and_normalize_path("a", "b/");        # -> "a/b"
     $p = concat_and_normalize_path("a", "../b/");     # -> "b"
     $p = concat_and_normalize_path("a/b", ".././c");  # -> "a/c"
     $p = concat_and_normalize_path("../", ".././c/"); # -> "../../c"

     # abs_path($path, $base) is equal to concat_path_n($base, $path). $base must be
     # absolute.
     $p = abs_path("a", "b");              # dies, $base is not absolute
     $p = abs_path("a", "/b");             # -> "/b/a"
     $p = abs_path(".", "/b");             # -> "/b"
     $p = abs_path("a/c/..", "/b/");       # -> "/b/a"
     $p = abs_path("/a", "/b/c");          # -> "/a"

     # rel_path($path, $base) makes $path relative. the opposite of abs_path().
     $p = rel_path("a", "/b");             # dies, $path is not absolute
     $p = rel_path("/a", "b");             # dies, $base is not absolute
     $p = rel_path("/a", "/b");            # -> "../a"
     $p = rel_path("/b/c/e", "/b/d/f");    # -> "../../c/e"

DESCRIPTION
    This is yet another set of routines to manipulate abstract Unix-like
    paths. Abstract means not tied to actual filesystem. Unix-like means
    single-root tree, with forward slash "/" as separator, and "." and ".."
    to mean current- and parent directory. Naive means not having the
    concept of symlinks, so paths need not be traversed on a per-directory
    basis (see File::Spec::Unix where it mentions the word "naive").

    These routines can be useful if you have a tree data and want to let
    users walk around it using filesystem-like semantics. Some examples of
    where these routines are used: Config::Tree, Riap (App::riap).

FUNCTIONS
  abs_path($path, $base) => str
  concat_and_normalize_path($path1, $path2, ...) => str
  concat_path($path1, $path2, ...) => str
  is_abs_path($path) => bool
  is_rel_path($path) => bool
  normalize_and_split_path($path) => list
    Added in v0.043.

  normalize_path($path) => str
  rel_path($path, $base) => str
    Added in v0.043.

  split_path($path) => list
HOMEPAGE
    Please visit the project's homepage at
    <https://metacpan.org/release/Path-Naive>.

SOURCE
    Source repository is at <https://github.com/perlancar/perl-Path-Naive>.

SEE ALSO
    Path::Abstract a similar module. The difference is, it does not
    interpret "." and "..".

    File::Spec::Unix a similar module, with some differences in parsing
    behavior.

AUTHOR
    perlancar <perlancar@cpan.org>

CONTRIBUTOR
    Steven Haryanto <stevenharyanto@gmail.com>

CONTRIBUTING
    To contribute, you can send patches by email/via RT, or send pull
    requests on GitHub.

    Most of the time, you don't need to build the distribution yourself. You
    can simply modify the code, then test via:

     % prove -l

    If you want to build the distribution (e.g. to try to install it locally
    on your system), you can install Dist::Zilla,
    Dist::Zilla::PluginBundle::Author::PERLANCAR,
    Pod::Weaver::PluginBundle::Author::PERLANCAR, and sometimes one or two
    other Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps
    required beyond that are considered a bug and can be reported to me.

COPYRIGHT AND LICENSE
    This software is copyright (c) 2024, 2020, 2014, 2013 by perlancar
    <perlancar@cpan.org>.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

BUGS
    Please report any bugs or feature requests on the bugtracker website
    <https://rt.cpan.org/Public/Dist/Display.html?Name=Path-Naive>

    When submitting a bug or request, please include a test-file or a patch
    to an existing test-file that illustrates the bug or desired feature.

