Feature #14405

Add base option to Pathname.glob also

Added by pocke (Masataka Kuwabara) 23 days ago. Updated 19 days ago.

Target version:


Dir.glob has base option since Ruby 2.5.

However Pathname.glob does not have the option.
I would like to use base option with Pathname class.
But I feel Dir.glob('*.rb', base: 'dir').map{|path|Pathname(path)} is lengthy, so I'd like to add the option to Pathname.glob.

This patch adds the option to Pathname.glob also.

For example:

require 'pathname'

p Pathname.glob('lib/i*.rb', 0)                               # => [#<Pathname:lib/irb.rb>, #<Pathname:lib/ipaddr.rb>]
p Dir.glob('i*.rb', 0, base: 'lib')                           # => ["irb.rb", "ipaddr.rb"]
p Dir.glob('i*.rb', base: 'lib')                              # => ["irb.rb", "ipaddr.rb"]
p Pathname.glob('i*.rb', 0, base: 'lib')                      # => [#<Pathname:irb.rb>, #<Pathname:ipaddr.rb>]
p Pathname.glob('i*.rb', base: 'lib')                         # => [#<Pathname:irb.rb>, #<Pathname:ipaddr.rb>]
p Pathname.glob('i*.rb', base: Pathname('lib'))               # => [#<Pathname:irb.rb>, #<Pathname:ipaddr.rb>]
p Pathname.glob('i*.rb', base: Pathname(`pwd`.chomp) / 'lib') # => [#<Pathname:irb.rb>, #<Pathname:ipaddr.rb>]
p Pathname.glob('i*.rb', base: File.join(`pwd`.chomp, 'lib')) # => [#<Pathname:irb.rb>, #<Pathname:ipaddr.rb>]

Pathname.glob('i*.rb', foo: 'bar') rescue p $!                # => #<ArgumentError: unknown keyword: foo>
Pathname.glob('i*.rb', foo: 'bar') rescue p $!.backtrace      # => ["<...>/test.rb:13:in `glob'", "<...>/test.rb:13:in `glob'", "<...>/test.rb:13:in `<main>'"]

If the patch is OK, I'll do the follwoing TODOs.

pathname-glob-base.patch (597 Bytes) pathname-glob-base.patch pocke (Masataka Kuwabara), 01/26/2018 01:56 PM


#1 [ruby-core:85135] Updated by shevegen (Robert A. Heiler) 23 days ago

Probably makes sense so people can use either variant by default
depending on their personal preferences.

I personally love "Dir"-related methods; I think Dir[] is probably
the method I use the most in general when I need to find/obtain
files and directory. For me, Pathname was too lengthy. :)

#2 [ruby-core:85151] Updated by nobu (Nobuyoshi Nakada) 22 days ago

  • Status changed from Open to Feedback

Pathname has glob instance method.

p Pathname('lib').glob('i*.rb', 0) => [#<Pathname:lib/ipaddr.rb>, #<Pathname:lib/irb.rb>]

This looks brief enough.

#3 [ruby-core:85211] Updated by pocke (Masataka Kuwabara) 20 days ago

nobu (Nobuyoshi Nakada) wrote:

Pathname has glob instance method.

p Pathname('lib').glob('i*.rb', 0) => [#<Pathname:lib/ipaddr.rb>, #<Pathname:lib/irb.rb>]

This looks brief enough.

Definitely. I also noticed it after created this ticket.

However I think Pathname.glob makes sense for two reasons.
Firstly, I think Pathname.glob should have same interface as Dir.glob. For example, if they have the same interface, we can replace Dir.glob with Pathname.glob more easily.

# before
Dir.glob('*', base: 'path/to/dir')

# When I'd like to get pathnames:

# If they don't have the same interface, I should rewrite the whole code.

# If they have the same interface, I'll just replace `Dir` with `Pathname` only. I think it is more easily.
Pathname.glob('*', base: 'path/to/dir')

Secondly, I feel the Pathname('path/to/dir') is a subject in Pathname('path/to/dir').glob('*'), and base: 'path/to/dir' is not a subject in Pathname.glob('*', base: 'path/to/dir').
I guess a base directory is not a subject of the glob methods in many cases, so I'd like to use the keyword argument style in many cases.
Pathname('path/to/dir').glob('*')では、Pathname('path/to/dir')がこのコードの主役のように感じます。一方Pathname.glob('*', base: 'path/to/dir')の方ではbase: 'path/to/dir'はコードの主役ではないように感じます。

What do you think?

#4 [ruby-core:85244] Updated by nobu (Nobuyoshi Nakada) 19 days ago

  • Assignee set to akr (Akira Tanaka)
  • Status changed from Feedback to Assigned

Also available in: Atom PDF