mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
[DOC] Harmonize glob methods (#17265)
This commit is contained in:
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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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) }
|
||||
|
||||
Reference in new issue
Block a user