[DOC] Harmonize glob methods (#17265)

This commit is contained in:
Burdette Lamar authored and GitHub committed 2026-06-15 10:16:41 +09:00
1 parent 7c36a0cf62
commit 4530a17f58
3 files changed
+63 -228
Notes: git 2026-09-14 01:47:40 +00:00
Merged-By: peterzhu2118 <peter@peterzhu.ca>

No files matched your search

+5 -187
View File
@@ -213,200 +213,18 @@ class Dir
end
# call-seq:
# Dir[*patterns, base: nil, sort: true] -> array
#
# Calls Dir.glob with argument +patterns+
# and the values of keyword arguments +base+ and +sort+;
# returns the array of selected entry names.
# Dir[patterns, base: nil, sort: true] -> array
#
# Like Dir.glob, but does not accept keyword argument +flags+.
def self.[](*args, base: nil, sort: true)
Primitive.dir_s_aref(args, base, sort)
end
# call-seq:
# Dir.glob(patterns, flags: 0, base: nil, sort: true) -> array
# Dir.glob(patterns, flags: 0, base: nil, sort: true) {|entry_name| ... } -> nil
#
# Forms an array _entry_names_ of the entry names selected by the arguments.
#
# Argument +patterns+ is a string pattern or an array of string patterns;
# note that these are not regexps; see below.
#
# Notes for the following examples:
#
# - <tt>'*'</tt> is the pattern that matches any entry name
# except those that begin with <tt>'.'</tt>.
# - We use method Array#take to shorten returned arrays
# that otherwise would be very large.
#
# With no block, returns array _entry_names_;
# example (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]):
#
# Dir.glob('*') # => ["config.h", "lib", "main.rb"]
#
# With a block, calls the block with each of the _entry_names_
# and returns +nil+:
#
# Dir.glob('*') {|entry_name| puts entry_name } # => nil
#
# Output:
#
# config.h
# lib
# main.rb
#
# If optional keyword argument +flags+ is given,
# the value modifies the matching; see below.
#
# If optional keyword argument +base+ is given,
# its value specifies the base directory.
# Each pattern string specifies entries relative to the base directory;
# the default is <tt>'.'</tt>.
# The base directory is not prepended to the entry names in the result:
#
# Dir.glob(pattern, base: 'lib').take(5)
# # => ["abbrev.gemspec", "abbrev.rb", "base64.gemspec", "base64.rb", "benchmark.gemspec"]
# Dir.glob(pattern, base: 'lib/irb').take(5)
# # => ["cmd", "color.rb", "color_printer.rb", "completion.rb", "context.rb"]
#
# If optional keyword +sort+ is given, its value specifies whether
# the array is to be sorted; the default is +true+.
# Passing value +false+ with that keyword disables sorting
# (though the underlying file system may already have sorted the array).
#
# <b>Patterns</b>
#
# Each pattern string is expanded
# according to certain metacharacters;
# examples below use the {Ruby file tree}[rdoc-ref:Dir@About+the+Examples]:
#
# - <tt>'*'</tt>: Matches any substring in an entry name,
# similar in meaning to regexp <tt>/.*/mx</tt>;
# may be restricted by other values in the pattern strings:
#
# - <tt>'*'</tt> matches all entry names:
#
# Dir.glob('*').take(3) # => ["BSDL", "CONTRIBUTING.md", "COPYING"]
#
# - <tt>'c*'</tt> matches entry names beginning with <tt>'c'</tt>:
#
# Dir.glob('c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"]
#
# - <tt>'*c'</tt> matches entry names ending with <tt>'c'</tt>:
#
# Dir.glob('*c').take(3) # => ["addr2line.c", "array.c", "ast.c"]
#
# - <tt>'\*c\*'</tt> matches entry names that contain <tt>'c'</tt>,
# even at the beginning or end:
#
# Dir.glob('*c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"]
#
# Does not match Unix-like hidden entry names ("dot files").
# To include those in the matched entry names,
# use flag IO::FNM_DOTMATCH or something like <tt>'{*,.*}'</tt>.
#
# - <tt>'**'</tt>: Matches entry names recursively
# if followed by the slash character <tt>'/'</tt>:
#
# Dir.glob('**/').take(3) # => ["basictest/", "benchmark/", "benchmark/gc/"]
#
# If the string pattern contains other characters
# or is not followed by a slash character,
# it is equivalent to <tt>'*'</tt>.
#
# - <tt>'?'</tt> Matches any single character;
# similar in meaning to regexp <tt>/./</tt>:
#
# Dir.glob('io.?') # => ["io.c"]
#
# - <tt>'[set]'</tt>: Matches any one character in the string _set_;
# behaves like a {Regexp character class}[rdoc-ref:Regexp@Character+Classes],
# including set negation (<tt>'[^a-z]'</tt>):
#
# Dir.glob('*.[a-z][a-z]').take(3)
# # => ["CONTRIBUTING.md", "COPYING.ja", "KNOWNBUGS.rb"]
#
# - <tt>'{abc,xyz}'</tt>:
# Matches either string _abc_ or string _xyz_;
# behaves like {Regexp alternation}[rdoc-ref:Regexp@Alternation]:
#
# Dir.glob('{LEGAL,BSDL}') # => ["LEGAL", "BSDL"]
#
# More than two alternatives may be given.
#
# - <tt>\\</tt>: Escapes the following metacharacter.
#
# Note that on Windows, the backslash character may not be used
# in a string pattern:
# <tt>Dir['c:\\foo*']</tt> will not work, use <tt>Dir['c:/foo*']</tt> instead.
#
# More examples (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]):
#
# # We're in the example directory.
# File.basename(Dir.pwd) # => "example"
# Dir.glob('config.?') # => ["config.h"]
# Dir.glob('*.[a-z][a-z]') # => ["main.rb"]
# Dir.glob('*.[^r]*') # => ["config.h"]
# Dir.glob('*.{rb,h}') # => ["main.rb", "config.h"]
# Dir.glob('*') # => ["config.h", "lib", "main.rb"]
# Dir.glob('*', File::FNM_DOTMATCH) # => [".", "config.h", "lib", "main.rb"]
# Dir.glob(["*.rb", "*.h"]) # => ["main.rb", "config.h"]
#
# Dir.glob('**/*.rb')
# => ["lib/song/karaoke.rb", "lib/song.rb", "main.rb"]
#
# Dir.glob('**/*.rb', base: 'lib') # => ["song/karaoke.rb", "song.rb"]
#
# Dir.glob('**/lib') # => ["lib"]
#
# Dir.glob('**/lib/**/*.rb') # => ["lib/song/karaoke.rb", "lib/song.rb"]
#
# Dir.glob('**/lib/*.rb') # => ["lib/song.rb"]
#
# <b>Flags</b>
#
# If optional keyword argument +flags+ is given (the default is zero -- no flags),
# its value should be the bitwise OR of one or more of the constants
# defined in module File::Constants.
#
# Example:
#
# flags = File::FNM_EXTGLOB | File::FNM_DOTMATCH
#
# Specifying flags can extend, restrict, or otherwise modify the matching.
#
# The flags for this method (other constants in File::Constants do not apply):
#
# - File::FNM_DOTMATCH:
# specifies that entry names beginning with <tt>'.'</tt>
# should be considered for matching:
#
# Dir.glob('*').take(5)
# # => ["BSDL", "CONTRIBUTING.md", "COPYING", "COPYING.ja", "GPL"]
# Dir.glob('*', flags: File::FNM_DOTMATCH).take(5)
# # => [".", ".appveyor.yml", ".cirrus.yml", ".dir-locals.el", ".document"]
#
# - File::FNM_EXTGLOB:
# enables the pattern extension
# <tt>'{a,b}'</tt>, which matches pattern _a_ and pattern _b_;
# behaves like a
# {regexp union}[rdoc-ref:Regexp.union]
# (e.g., <tt>'(?:a|b)'</tt>):
#
# pattern = '{LEGAL,BSDL}'
# Dir.glob(pattern) # => ["LEGAL", "BSDL"]
#
# - File::FNM_NOESCAPE:
# specifies that escaping with the backslash character <tt>'\'</tt>
# is disabled; the character is not an escape character.
#
# - File::FNM_PATHNAME:
# specifies that metacharacters <tt>'*'</tt> and <tt>'?'</tt>
# do not match directory separators.
#
# - File::FNM_SHORTNAME:
# specifies that patterns may match short names if they exist; Windows only.
# Dir.glob(patterns, flags: 0, base: '.', sort: true) -> array_of_entries
#
# Returns an array of filesystem entries;
# see {Filename Globbing}[rdoc-ref:file/filename_globbing.md].
def self.glob(pattern, _flags = 0, flags: _flags, base: nil, sort: true)
Primitive.attr! :use_block
Primitive.dir_s_glob(pattern, flags, base, sort)
+48 -5
View File
@@ -3,17 +3,58 @@
Filename globbing is a pattern-matching feature implemented in certain Ruby methods:
- Dir.glob.
- [`Dir[]`](https://docs.ruby-lang.org/en/master/Dir.html#method-c-5B-5D).
- Pathname.glob.
- Pathname#glob.
- [`Dir[]`](../Dir.html#method-c-5B-5D),
which is like Dir.glob except that it does not accept keyword argument `flags`.
Each `glob` method finds filesystem entries (files and directories)
that match certain patterns.
Each `glob` method selects filesystem entries (file and directory names)
that match certain patterns,
under the control of keyword arguments `base` and `flags`;
the selected entries may be sorted, according to keyword argument `sort`.
These methods are quite different
These filename-globbing methods are quite different
from [filename-matching](rdoc-ref:filename_matching.md) methods,
which match patterns against string paths, and do not access the filesystem.
Inputs to the filename-globbing methods:
- The argument `patterns` is a string or an array of strings,
which are _not_ Regexp objects;
see [Patterns](#patterns).
- Keyword argument `base` specifies the entry in the filesystem where searching is to begin;
see [base](#base).
- Keyword argument `flags` specifies an integer value that may be defined by constants;
see [flags](#flags).
This argument is not available
in method [`Dir[]`](https://docs.ruby-lang.org/en/master/Dir.html#method-c-5B-5D),
for which the flags value is zero.
- Keyword argument `sort` specifies whether the returned array is to be sorted.
see [sort](#sort).
Their return values:
- Each of the methods `Dir[]` and Dir.glob returns an array of the selected string entries.
- \Method Pathname#glob with no block returns an array of Pathname objects
each based on a selected string entry.
- \Method Pathname#glob with a block calls the block with each pathname
based on a selected string entry.
Examples:
```ruby
Dir['*'].take(3)
# => ["BSDL", "CONTRIBUTING.md", "COPYING"]
Dir.glob('*').take(3)
# => ["BSDL", "CONTRIBUTING.md", "COPYING"]
Pathname('.').glob('*').take(3)
# => [#<Pathname:BSDL>, #<Pathname:CONTRIBUTING.md>, #<Pathname:COPYING>]
a = []
Pathname('.').glob('*') {|pn| a << pn if pn.to_s.end_with?('.c') } # => nil
a.take(3) # => [#<Pathname:addr2line.c>, #<Pathname:array.c>, #<Pathname:ast.c>]
```
The examples below for Pathname#glob do not give blocks.
## Patterns
These are the basic elements of filename-globbing patterns;
@@ -314,6 +355,8 @@ Pathname('lib/net').glob('*').take(3)
# => [#<Pathname:lib/net/http>, #<Pathname:lib/net/http.rb>, #<Pathname:lib/net/https.rb>]
```
Note that the base directory is not prepended to the entry names in the result.
### `flags`
Optional keyword argument `flags` (defaults to `0`) may be the bitwise OR
+10 -36
View File
@@ -1777,47 +1777,21 @@ class Pathname # * FileTest *
end
class Pathname # * Dir *
class Pathname
# call-seq:
# glob(patterns, **kwargs) → array_of_pathnames
# glob(patterns, **kwargs) {|pathname| ... } → nil
# glob(patterns, base: '.', flags: 0, sort: true) → array_of_pathnames
# glob(patterns, base: '.', flags: 0, sort: true) {|pathname| ... } → nil
#
# Calls <tt>Dir.glob(patterns, **kwargs)</tt>, which yields or returns entry names;
# see Dir.glob.
# Selects filesystem entries
# based on the given keyword arguments +base+, +flags+, and +sort+;
# see {Filename Globbing}[rdoc-ref:file/filename_globbing.md].
#
# Required argument +patterns+ is a string pattern or an array of string patterns;
# note that these patterns are not regexps.
# With no block given, returns an array of pathnames,
# each based on a selected filesystem entry.
#
# Keyword arguments <tt>**kwargs</tt> are passed through to Dir.glob;
# see the documentation there.
# With a block given, calls the block with pathnames,
# each based on a selected filesytem entry.
#
# With no block given, returns an array of \Pathname objects;
# each is <tt>Pathname.new(entry_name)</tt> for an entry name returned by Dir.glob.
#
# Pathname.glob('*').take(3)
# # => [#<Pathname:BSDL>, #<Pathname:CONTRIBUTING.md>, #<Pathname:COPYING>]
# Pathname.glob(['o*', 'a*']).take(3)
# # => [#<Pathname:object.c>, #<Pathname:aclocal.m4>, #<Pathname:addr2line.c>]
#
# With a block given, calls the block with each pathname
# <tt>Pathname.new(entry_name)</tt>,
# where each +entry_name+ is a \Pathname object created by the value yielded by Dir.glob.
#
# a = []
# Pathname.glob(['o*', 'a*']) {|pathname| a << pathname }
# a.take(3)
# # => [#<Pathname:object.c>, #<Pathname:aclocal.m4>, #<Pathname:addr2line.c>]
#
# Optional keyword argument +base+ is of particular interest.
# When it is given, its value specifies the base directory for the pathnames;
# each pattern string specifies entries relative to the base directory:
#
# Pathname.glob('*', base: 'lib').take(2)
# # => [#<Pathname:English.gemspec>, #<Pathname:English.rb>]
# Pathname.glob('*', base: 'lib/bundler').take(2)
# # => [#<Pathname:build_metadata.rb>, #<Pathname:bundler.gemspec>]
#
# Note that the base directory is not prepended to the entry names in the result.
def Pathname.glob(*args, **kwargs) # :yield: pathname
if block_given?
Dir.glob(*args, **kwargs) {|f| yield self.new(f) }