Skip to content

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

Open

Description

@kenjitayama

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 "/".

Activity

  1. kylef commented on Mar 22, 2016

    @kylef
    Owner

    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
  2. kenjitayama commented on Mar 22, 2016

    @kenjitayama
    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.

  3. kenjitayama commented on Mar 24, 2016

    @kenjitayama
    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.

  4. rbukovansky commented on Oct 11, 2016

    @rbukovansky
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions