Project

General

Profile

Feature #11302

Dir.entries and Dir.foreach without [".", ".."]

Added by naruse (Yui NARUSE) over 2 years ago. Updated 2 months ago.

Status:
Closed
Priority:
Normal
Target version:
-
[ruby-dev:49135]

Description

Dir.entries returns an array of its content with "." and "..".
But as far as I met, almost all cases don't need them.

How about adding such new method or options?


Related issues

Related to Ruby trunk - Feature #13789: Dir - methodsRejected
Related to Ruby trunk - Feature #13969: Dir#each_childOpen

Associated revisions

Revision 58879
Added by nobu (Nobuyoshi Nakada) 6 months ago

dir.c: Dir.each_child and Dir.children

  • dir.c (dir_s_each_child, dir_s_children): Dir.each_child and Dir.children which are similar to Dir.foreach and Dir.entries respectively, except to exclude "." and "..". [Feature #11302]

Revision 59926
Added by naruse (Yui NARUSE) 2 months ago

Find.find -> Use Dir.children instead of Dir.entries

Dir.children is available since Feature #11302.
Find.find can use of the new list (having no '.' neither '..' entries),
making now superflous an if statement.

This change can improve the performance of Find.find when the path
has lots of entries (thousands?).

https://bugs.ruby-lang.org/issues/11302
patched by Espartaco Palma esparta@gmail.com
https://github.com/ruby/ruby/pull/1697 fix GH-1697
[Feature #13896]

History

#1 [ruby-dev:49136] Updated by nobu (Nobuyoshi Nakada) over 2 years ago

Candidates for the methods or options?

I prefer a same option for both methods, but no concrete idea.

#2 [ruby-dev:49138] Updated by red (Arnaud Rouyer) over 2 years ago

Nobuyoshi Nakada wrote:

Candidates for the methods or options?

I prefer a same option for both methods, but no concrete idea.

Dir.foreach and Dir.entries both support a second hash argument for options: as of 2.2.2, the docs only mention the :encoding key in the options hash.

Basing myself on the GNU ls util, I propose supporting an :ignore key in the optional hash argument.

We could have an API similar to this:

$ ls -a
.
..
.hidden_file
directory
file.bin

$ irb

irb:001> Dir.entries('.')
 => [".", "..", ".hidden_file", "directory", "file.bin"]
irb:002> Dir.entries('.', ignore: :almost_all)  # almost_all option name taken from GNU ls option name
 => [".hidden_file", "directory", "file.bin"]   # http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c#n4784
irb:003> Dir.entries('.', ignore: :directories)
=> [".hidden_file", "file.bin"]
irb:004> Dir.entries('.', ignore: :hidden)
=> ["directory", "file.bin"]

# Fancy proposal
irb:005> Dir.entries('.', ignore: /o/)
=> [".", "..", ".hidden_file", "file.bin"]

Edit after a closer look:

Internally, Dir.entries and Dir.foreach both call Dir.new and use the resulting Dir object's #to_a and #each methods respectively to return an array/an enumerator. If we want to go down this path, these options have to be supported in Dir.new, stored in the Dir instance and reused in the #each enumerator to filter out ignored entries.

#3 [ruby-dev:50021] Updated by olivierlacan (Olivier Lacan) 8 months ago

red (Arnaud Rouyer) wrote:

Basing myself on the GNU ls util, I propose supporting an :ignore key in the optional hash argument.

I very much like this. I just ran into this issue myself today having to remove . and .. from Dir.entries output.

I don't think the ignore option accepting a regex is fancy at all, it makes a ton of sense. An array should also be acceptable considering that Dir.entries('.', ignore: %w[. ..]) would become equivalent to:

Dir.entries('.') - %w[. ..]

I find it quite elegant, and certainly a lot more discoverable than GNU ls style arguments. :-)

#4 [ruby-dev:50087] Updated by nobu (Nobuyoshi Nakada) 7 months ago

red (Arnaud Rouyer) wrote:

Basing myself on the GNU ls util, I propose supporting an :ignore key in the optional hash argument.

irb:002> Dir.entries('.', ignore: :almost_all)  # almost_all option name taken from GNU ls option name

ignore: :almost_all seems like that almost all files will be ignored and only '.' and '..' will be returned.

#5 [ruby-dev:50126] Updated by akr (Akira Tanaka) 6 months ago

There is Pathname#children and Pathname#each_child.

How about Dir.children and Dir.each_child ?

#6 [ruby-dev:50127] Updated by shyouhei (Shyouhei Urabe) 6 months ago

+1 for Dir.children

#7 [ruby-dev:50128] Updated by matz (Yukihiro Matsumoto) 6 months ago

Sounds good.

Matz.

#8 Updated by nobu (Nobuyoshi Nakada) 6 months ago

  • Status changed from Assigned to Closed

Applied in changeset trunk|r58879.


dir.c: Dir.each_child and Dir.children

  • dir.c (dir_s_each_child, dir_s_children): Dir.each_child and Dir.children which are similar to Dir.foreach and Dir.entries respectively, except to exclude "." and "..". [Feature #11302]

#9 Updated by Eregon (Benoit Daloze) 2 months ago

#10 [ruby-dev:50242] Updated by Eregon (Benoit Daloze) 2 months ago

The decision here is surprising given https://bugs.ruby-lang.org/issues/13789#note-3
but nevertheless I'm very happy this got accepted.

#11 Updated by znz (Kazuhiro NISHIYAMA) about 2 months ago

Also available in: Atom PDF