Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behavior of joining paths starting with "/" is unnatural #12

Open
kenjitayama opened this issue Mar 22, 2016 · 4 comments
Open

Behavior of joining paths starting with "/" is unnatural #12

kenjitayama opened this issue Mar 22, 2016 · 4 comments

Comments

@kenjitayama
Copy link

I think the following joining behavior is unnatural.

let path = Path("/usr/bin") + Path("/swift") // becomes "/swift" instead of "/usr/bin/swift"

Implemented here:

// Absolute paths replace relative paths

I think it is common to build paths with, left hand side not ending with "/" and right handing side starting with "/".

@kylef
Copy link
Owner

kylef commented Mar 22, 2016

I disagree that this is unnatural, it's actually consistent with many other languages and join implementations. It's exactly how I'd expect it to work.

Could you perhaps explain your use-case a bit more so we can try and find a different solution? Why would your right hand have a slash in it already?

A cross-platform solution would look more like:

let root = Path(Path.separator)
let usrBin = (root + "usr") + "bin"
let swift = usrBin + "swift"

If you're supporting multiple platforms, you cannot rely on the fact that / is the separator, it could be something else such as \. The whole point around this API is to join paths without hard-coding "/" as a string everywhere.

Python

https://docs.python.org/3.5/library/os.path.html#os.path.join

If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.

>>> from os import path
>>> path.join("/usr/local", "/swift")
'/swift'

Ruby

Can't find a statement in the documentation, but you can see the behaviour is the same:

> Pathname.new('/usr/bin').join('/swift')
=> #<Pathname:/swift>

Cocoa (NSURL)

Again, I can't find a part of the documentation, but here is the behaviour.

NSURL(fileURLWithPath: "/swift", relativeToURL:NSURL(fileURLWithPath: "/usr/bin"))
// --> file:///swift

@kenjitayama
Copy link
Author

Thank you for explaining in detail.
I see you're pretty right that it's consistent and natural.

I had one counter example in mind.

let basePath = NSURL(fileURLWithPath: "/base/path")
let path = basePath.URLByAppendingPathComponent("/some/path")
// --> file:///base/path/some/path

Anyways, my use case is…
I have some generated swift code that I can't control, and has let path = "/some/path" in it.
And I need to concatinate it to a let basePath = Path("/base/path").
With the current implementation, I need to String(path.characters.dropFirst()) before concatination.
These paths are acutually part of a URL, so I don't need to worry about path separators.

Would you say this is not a use case for PathKit, or am I missing a better approach using PathKit?

Thanks in advance for advice.

@kenjitayama
Copy link
Author

I found this behaviour in Ruby.

base_path = "/base/path"
path = "/some/path"
result_path = File.join(base_path, path) // => /base/path/some/path

I think, at least there are some demands for this style of concatination.

@rbukovansky
Copy link
Contributor

Boy, I don't want to see debate about this when Apple or somebody brings Swift to Windows... (slash and backslash works both, drives' letters etc.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants