NAME

Developer::Dashboard::PathIdentity - shared canonical path identity helper

SYNOPSIS

use Developer::Dashboard::PathIdentity qw(_path_identity _same_or_descendant_path);

my $id = _path_identity( $path, empty_fallback => 1 );
my $is_descendant = _same_or_descendant_path( $path, $root, empty_fallback => 1 );

DESCRIPTION

Provides _path_identity and _same_or_descendant_path, the single home for a path-normalization pair that used to be written out twice, once in Developer::Dashboard::PathRegistry (as instance methods) and once in Developer::Dashboard::EnvLoader (as class methods) (DD-903) - the same "small helper reimplemented per file instead of shared" pattern this project already fixed in Developer::Dashboard::DirEntries (DD-762), Developer::Dashboard::TextUtils (DD-891), Developer::Dashboard::TimeUtils (DD-894), and Developer::Dashboard::IsoTimestamp (DD-904).

PURPOSE

Give every module that needs to compare filesystem paths for identity or ancestry one canonical implementation to call, in either of the two edge-case behaviors this project's two former copies actually used, rather than each maintaining its own private copy that can silently drift.

WHY IT EXISTS

PathRegistry.pm's _path_identity and EnvLoader.pm's _path_identity were nearly byte-identical, differing only in invocation style ($self vs $class) - except for one genuine behavioral divergence: when Cwd::abs_path() returns an empty string (as opposed to undef) for a path, PathRegistry.pm's version falls back to File::Spec->canonpath($path), while EnvLoader.pm's version returns the empty string as-is. Both versions already agreed on the undef case (both fall back to canonpath).

Rather than silently pick one behavior and risk changing the other file's real (if rare) semantics, this module takes an explicit empty_fallback => 1|0 parameter with no default, mirroring this project's TimeUtils.pm tz and IsoTimestamp.pm on_error precedent: empty_fallback => 1 reproduces PathRegistry.pm's historical behavior, empty_fallback => 0 reproduces EnvLoader.pm's.

WHEN TO USE

Whenever code needs to compare two filesystem paths for identity or ancestry across possible symlink aliases (e.g. /var vs /private/var on macOS), rather than comparing raw path strings.

HOW TO USE

use Developer::Dashboard::PathIdentity qw(_path_identity _same_or_descendant_path);

my $id = _path_identity( $path, empty_fallback => 1 );
if ( _same_or_descendant_path( $candidate, $root, empty_fallback => 1 ) ) {
    ...
}

Both functions require empty_fallback to be passed explicitly; there is no default, so a caller cannot silently inherit the wrong edge-case behavior for its own historical call sites.

WHAT USES IT

Developer::Dashboard::PathRegistry (via empty_fallback => 1) and Developer::Dashboard::EnvLoader (via empty_fallback => 0).

EXAMPLES

_path_identity( '/var/tmp', empty_fallback => 1 );
# => '/private/var/tmp' on macOS (a real existing path resolves via abs_path)

_same_or_descendant_path( '/home/me/project/sub', '/home/me/project', empty_fallback => 0 );
# => 1 (true)