From 0fb38290bb87356159734c47f44c99e5b1940fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Sun, 28 Feb 2021 14:38:46 +0100 Subject: [PATCH 1/3] Clarify documentation on `Path#join` and `#==` --- src/path.cr | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/path.cr b/src/path.cr index 8fc7650232f1..cbaf8b9657c8 100644 --- a/src/path.cr +++ b/src/path.cr @@ -290,9 +290,15 @@ struct Path # # If *suffix* is given, it is stripped from the end. # + # In case the last component is the empty string (i.e. the path has a trailing + # separator), the second to last component is returned. + # For path that only consists of an anchor, or an empty path, the base name + # is equivalent to the full path. + # # ``` # Path["/foo/bar/file.cr"].basename # => "file.cr" # Path["/foo/bar/"].basename # => "bar" + # Path["/foo/bar/."].basename # => "bar" # Path["/"].basename # => "/" # Path[""].basename # => "" # ``` @@ -793,6 +799,16 @@ struct Path # Path["foo/"].join("/bar") # => Path["foo/bar"] # Path["/foo/"].join("/bar/") # => Path["/foo/bar/"] # ``` + # + # Joining an empty string (`""`) appends a trailing path separator. + # In case the path already ends with a trailing separator, no additional + # separator is added. + # + # ``` + # Path["a/b"].join("") # => Path["a/b/"] + # Path["a/b/"].join("") # => Path["a/b/"] + # Path["a/b/"].join("c") # => Path["a/b/c"] + # ``` def join(part) : Path # If we are joining a single part we can use `String.new` instead of # `String.build` which avoids an extra allocation. @@ -862,6 +878,8 @@ struct Path # Path["foo/"].join("/bar/", "/baz") # => Path["foo/bar/baz"] # Path["/foo/"].join("/bar/", "/baz/") # => Path["/foo/bar/baz/"] # ``` + # + # See `join(part)` for details. def join(*parts) : Path join parts end @@ -880,6 +898,8 @@ struct Path # Path.posix("foo/bar").join(Path.windows("baz\\baq")) # => Path.posix("foo/bar/baz/baq") # Path.windows("foo\\bar").join(Path.posix("baz/baq")) # => Path.windows("foo\\bar\\baz/baq") # ``` + # + # See `join(part)` for details. def join(parts : Enumerable) : Path if parts.is_a?(Indexable) return self if parts.empty? @@ -952,6 +972,8 @@ struct Path # Path["foo"] / "bar" / "baz" # => Path["foo/bar/baz"] # Path["foo/"] / Path["/bar/baz"] # => Path["foo/bar/baz"] # ``` + # + # See `join(part)` for details. def /(part : Path | String) : Path join(part) end @@ -1063,12 +1085,14 @@ struct Path # Compares this path to *other*. # # The comparison is performed strictly lexically: `foo` and `./foo` are *not* - # treated as equal. To compare paths semantically, they need to be normalized - # and converted to the same kind. + # treated as equal. Nor are paths of different `kind`. + # To compare paths semantically, they need to be normalized and converted to + # the same kind. # # ``` # Path["foo"] <=> Path["foo"] # => 0 # Path["foo"] <=> Path["./foo"] # => 1 + # Path["foo"] <=> Path["foo/"] # => 1 # Path.posix("foo") <=> Path.windows("foo") # => -1 # ``` # @@ -1086,6 +1110,27 @@ struct Path @kind <=> other.@kind end + # Returns `true` if this path is considered equivalent to *other*. + # + # The comparison is performed strictly lexically: `foo` and `./foo` are *not* + # treated as equal. Nor are paths of different `kind`. + # To compare paths semantically, they need to be normalized and converted to + # the same kind. + # + # ``` + # Path["foo"] == Path["foo"] # => true + # Path["foo"] == Path["./foo"] # => false + # Path["foo"] == Path["foo/"] # => false + # Path.posix("foo") == Path.windows("foo") # => false + # ``` + # + # Comparison is case-sensitive for POSIX paths and case-insensitive for + # Windows paths. + # + # ``` + # Path.posix("foo") == Path.posix("FOO") # => false + # Path.windows("foo") == Path.windows("FOO") # => true + # ``` def ==(other : self) return false if @kind != other.@kind From 11e8dade8cc8893dfa1ce9cc0ae8fee489d3845e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Sun, 28 Feb 2021 23:34:30 +0100 Subject: [PATCH 2/3] Fix typo --- src/path.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/path.cr b/src/path.cr index cbaf8b9657c8..f4544e6f81f0 100644 --- a/src/path.cr +++ b/src/path.cr @@ -298,7 +298,7 @@ struct Path # ``` # Path["/foo/bar/file.cr"].basename # => "file.cr" # Path["/foo/bar/"].basename # => "bar" - # Path["/foo/bar/."].basename # => "bar" + # Path["/foo/bar/."].basename # => "." # Path["/"].basename # => "/" # Path[""].basename # => "" # ``` From b35605153050c633d4afe81b2de58c48bcdef75c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Tue, 1 Jun 2021 11:10:37 +0200 Subject: [PATCH 3/3] Update src/path.cr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jonne Haß --- src/path.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/path.cr b/src/path.cr index f4544e6f81f0..2a0bccc012af 100644 --- a/src/path.cr +++ b/src/path.cr @@ -292,7 +292,7 @@ struct Path # # In case the last component is the empty string (i.e. the path has a trailing # separator), the second to last component is returned. - # For path that only consists of an anchor, or an empty path, the base name + # For a path that only consists of an anchor, or an empty path, the base name # is equivalent to the full path. # # ```