Path as an object in std.path

Dylan Knutson tcdknutson at gmail.com
Wed Jun 5 15:26:22 PDT 2013


I'd like to point out some of the pitfalls of using a raw string
as a representation of a path, too.

You've got to manually normalize strings before any comparison is
done. Even a single directory delimer at the end of the string
means that the paths won't compare correctly. This takes a good
amount of extra code to do so, and you've got to remember to
normalize *everywhere*, or you've got a bug waiting to happen.
string s1 = `baz/../foo/bar/`;
string s2 = `foo/bar/`;
string s3 = `foo/bar`;

assert(s1 == s2); // Fails
assert(s2 == s3); // Fails
assert(s1 == s3); // Fails
assert(buildNormalizedPath(s1) == buildNormalizedPath(s2)); //
Passes, with many more keystrokes.

Comparing with Paths:
Path p1 = `baz/../foo/bar/`;
Path p2 = `foo/bar/`;
Path p2 = `foo/bar`;

assert(p1 == p2); // Passes.
assert(p2 == p3); // Passes.
assert(p1 == p3); // Passes.

As you can see, Path is just generally easier to work with,
because it encapsulates the concept a path. There's no having to
normalize strings, because that's done for you. It just works.

Building a path with strings isn't difficult, but the function
calls are unweildy.
string s1 = buildNormalizedPath(`foo`, `bar`);
string s2 = buildNormalizedPath(s1, `baz`);
assert(s2 == `foo/bar/baz`); // Will fail on some platforms.

Building a Path, IMO, just looks cleaner, and it's obvious what
you're doing.
Path p1 = Path(`foo`, `bar`);
Path p2 = p1.join(`baz`);
assert(p2 == `foo/bar/baz`); // Passes on all platforms.

As a sidenote, I'd like to point out that using Path has *no more
overhead* than passing around and manipulating a raw string.
As far as I can tell, all use cases for Path takes less code, and
more easily convays what you're doing. D's support for object
oriented design is great; why not make use of it?


More information about the Digitalmars-d mailing list