Bug #16831
closedRunning `Pathname#glob` with `File::FNM_DOTMATCH` option loses `.` and `..`
Description
Running Dir.glob
, Pathname.glob
with File::FNM_DOTMATCH
option keeps .
and ..
as their basename:
require 'pathname'
pathname = Pathname.pwd
#=> #<Pathname:/Users/jnito/dev>
# Dir.glob keeps "." and ".."
Dir.glob(pathname.join('*'), File::FNM_DOTMATCH).sort[0..1]
#=> ["/Users/jnito/dev/.", "/Users/jnito/dev/.."]
# Pathname.glob keeps "." and ".." too
Pathname.glob(pathname.join('*'), File::FNM_DOTMATCH).sort[0..1]
#=> [#<Pathname:/Users/jnito/dev/.>, #<Pathname:/Users/jnito/dev/..>]
I expect Pathname#glob
with File::FNM_DOTMATCH
option has same behavior, but it loses .
and ..
:
# Pathname#glob loses "." and ".."
pathname.glob('*', File::FNM_DOTMATCH).sort[0..1]
#=> [#<Pathname:/Users/jnito>, #<Pathname:/Users/jnito/dev>]
I wanted to replace my code from Pathname.glob(pathname.join('*'), File::FNM_DOTMATCH)
to pathname.glob('*', File::FNM_DOTMATCH)
, but I couldn't do due to their incompatibility. So I want Pathname#glob
to keep .
and ..
.
Updated by nobu (Nobuyoshi Nakada) over 4 years ago
Actually .
and ..
entries are kept.
Just Pathname("/Users/jnito/dev/..")
is cleaned up as Pathname("/Users/jnito")
.
Updated by jnchito (Junichi Ito) over 4 years ago
nobu (Nobuyoshi Nakada) wrote in #note-1:
Actually
.
and..
entries are kept.
JustPathname("/Users/jnito/dev/..")
is cleaned up asPathname("/Users/jnito")
.
That's true, but I feel the following code should have consistent results:
require 'pathname'
pathname = Pathname.pwd
Pathname(Dir.glob(pathname.join('*'), File::FNM_DOTMATCH).sort[0]).basename.to_s
#=> .
Pathname.glob(pathname.join('*'), File::FNM_DOTMATCH).sort[0].basename.to_s
#=> .
# This line doesn't return "."
pathname.glob('*', File::FNM_DOTMATCH).sort[0].basename.to_s
#=> jnito
Updated by Dan0042 (Daniel DeLorme) over 4 years ago
I don't think those can have consistent results, because Pathname#glob is equivalent to using the base
option of Dir.glob
and then joining the paths, which is not the same as joining the paths into a glob and then invoking Dir.glob
. In particular they have different behavior if the base contains globbing characters. And I don't think there's a method of Pathname that allows to join without cleaning the path.
b = Pathname.new("ext")
b.glob("*").min #=> #<Pathname:ext/-test->
Dir.glob("*", base: b).min #=> "-test-"
Dir.glob(b+"*").min #=> "ext/-test-"
b = Pathname.new("{ext,man}")
b.glob("*").min #=> nil because there's no literal "{ext,man}" dir
Dir.glob("*", base: b).min #=> nil
Dir.glob(b+"*").min #=> "ext/-test-"
Updated by jnchito (Junichi Ito) over 4 years ago
Thank you for your explanation. With your hint and reading the implementation code solved my question.
Dan0042 (Daniel DeLorme) wrote in #note-3:
I don't think those can have consistent results, because Pathname#glob is equivalent to using the
base
option ofDir.glob
and then joining the paths, which is not the same as joining the paths into a glob and then invokingDir.glob
. In particular they have different behavior if the base contains globbing characters. And I don't think there's a method of Pathname that allows to join without cleaning the path.b = Pathname.new("ext") b.glob("*").min #=> #<Pathname:ext/-test-> Dir.glob("*", base: b).min #=> "-test-" Dir.glob(b+"*").min #=> "ext/-test-" b = Pathname.new("{ext,man}") b.glob("*").min #=> nil because there's no literal "{ext,man}" dir Dir.glob("*", base: b).min #=> nil Dir.glob(b+"*").min #=> "ext/-test-"
Dan0042 (Daniel DeLorme) wrote in #note-3:
I don't think those can have consistent results, because Pathname#glob is equivalent to using the
base
option ofDir.glob
and then joining the paths, which is not the same as joining the paths into a glob and then invokingDir.glob
. In particular they have different behavior if the base contains globbing characters. And I don't think there's a method of Pathname that allows to join without cleaning the path.b = Pathname.new("ext") b.glob("*").min #=> #<Pathname:ext/-test-> Dir.glob("*", base: b).min #=> "-test-" Dir.glob(b+"*").min #=> "ext/-test-" b = Pathname.new("{ext,man}") b.glob("*").min #=> nil because there's no literal "{ext,man}" dir Dir.glob("*", base: b).min #=> nil Dir.glob(b+"*").min #=> "ext/-test-"
Updated by jeremyevans0 (Jeremy Evans) over 4 years ago
- Status changed from Open to Closed
Updated by Eregon (Benoit Daloze) about 4 years ago
- Related to Bug #17280: Dir.glob with FNM_DOTMATCH matches ".." and "." and results in duplicated entries added