Skip to content

Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →

instance method

Pathname#cleanpath

(?::boolish consider_symlink) -> ::Pathname
cleanpath(symlinks = false) → new_pathname

Returns a new Pathname object, “cleaned” of unnecessary separators, single-dot entries, and double-dot entries.

When self is empty, returns a pathname with a single-dot entry:

Example
Pathname('').cleanpath # => #<Pathname:.>

Separators

A lone separator is preserved:

Example
Pathname('/').cleanpath # => #<Pathname:/>

Multiple trailing separators are removed:

Example
Pathname('foo/////').cleanpath # => #<Pathname:foo>
Pathname('foo/').cleanpath     # => #<Pathname:foo>

Multiple embedded separators are reduced to a single separator:

Example
Pathname('foo///bar').cleanpath # => #<Pathname:foo/bar>

Multiple leading separators are reduced:

Example
# On Windows, where File.dirname('//') == '//'.
Pathname('/////foo').cleanpath # => #<Pathname://foo>
Pathname('/////').cleanpath    # => #<Pathname://>
# Otherwise, where File.dirname('//') == '/'.
Pathname('/////foo').cleanpath # => #<Pathname:/foo>
Pathname('/////').cleanpath    # => #<Pathname:/>

Single-Dot Entries

A lone single-dot entry is preserved:

Example
Pathname('.').cleanpath  # => #<Pathname:.>

A non-lone single-dot entry, regardless of its location, is removed:

Example
Pathname('foo/././././bar').cleanpath  # => #<Pathname:foo/bar>
Pathname('./foo/./././bar').cleanpath  # => #<Pathname:foo/bar>
Pathname('foo/./././bar/./').cleanpath # => #<Pathname:foo/bar>

Double-Dot Entries

A lone double-dot entry is preserved:

Example
Pathname('..').cleanpath # => #<Pathname:..>

When a non-lone double-dot entry is preceded by a named entry, both are removed:

Example
Pathname('foo/..').cleanpath          # => #<Pathname:.>
Pathname('foo/../bar').cleanpath      # => #<Pathname:bar>
Pathname('foo/../bar/..').cleanpath   # => #<Pathname:.>
Pathname('foo/bar/./../..').cleanpath # => #<Pathname:.>

When a non-lone double-dot entry is not preceded by a named entry, it is preserved:

Example
Pathname('../..').cleanpath # => #<Pathname:../..>

A non-lone meaningless double-dot entry is removed:

Example
Pathname('/..').cleanpath    # => #<Pathname:/>
Pathname('/../..').cleanpath # => #<Pathname:/>

Symbolic Links

If the path may contain symbolic links, consider give optional argument symlinks as true; the method then uses a more conservative algorithm that avoids breaking symbolic links. This may preserve more double-dot entries than are absolutely necessary, but without accessing the filesystem, this can’t be avoided.

Examples:

Example
Pathname('a/').cleanpath           # => #<Pathname:a>
Pathname('a/').cleanpath(true)     # => #<Pathname:a/>

Pathname('a/.').cleanpath          # => #<Pathname:a>
Pathname('a/.').cleanpath(true)    # => #<Pathname:a/.>

Pathname('a/./').cleanpath         # => #<Pathname:a>
Pathname('a/./').cleanpath(true)   # => #<Pathname:a/.>

Pathname('a/b/.').cleanpath        # => #<Pathname:a/b>
Pathname('a/b/.').cleanpath(true)  # => #<Pathname:a/b/.>

Pathname('a/../.').cleanpath       # => #<Pathname:.>
Pathname('a/../.').cleanpath(true) # => #<Pathname:a/..>

Pathname('a/b/../../../../c/../d').cleanpath
# => #<Pathname:../../d>
Pathname('a/b/../../../../c/../d').cleanpath(true)
# => #<Pathname:a/b/../../../../c/../d>
See also #chown #ctime #chop_basename #delete also in 4.0 · 3.4 · 3.3 · 3.2 · 3.1 · 3.0