Dir.foreach not with patterns?

I like the Dir form (or its “glob” alternative). I used to write
recursive functions to search a directory tree. Then I discovered
Dir[‘**/*.rb’]. Not only is it easier, it’s also faster.

···


– Jim Weirich / Compuware
– FWP Capture Services
– Phone: 859-386-8855

-----Original Message-----
From: dblack@superlink.net [mailto:dblack@superlink.net]
Sent: Friday, September 12, 2003 1:44 PM
To: ruby-talk@ruby-lang.org
Subject: Re: Dir.foreach not with patterns?

Hi –

On Sat, 13 Sep 2003, Kurt V. Hindenburg wrote:

Why does the third one not work as expected? It appears that
Dir.foreach will not work with patterns…

#!/usr/bin/ruby

s = “/etc/host*”

#1
l = Dir[s]
p l

#2
Dir.foreach(“/etc”) { |d| p d }

#3
Dir.foreach(s) { |d| p d }

#4

This is wasteful

l = Dir[s]
l.each { |f| p f }

You don’t need two lines, though – you can do this in a way
that’s actually
shorter than #3:

Dir[s].each {|f| p f}

David


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Weirich, James wrote:

I like the Dir form (or its “glob” alternative). I used to write
recursive functions to search a directory tree. Then I discovered
Dir[‘**/*.rb’]. Not only is it easier, it’s also faster.

I’m not so sure. I timed my recursive “Filescan” class against Dir on
a large fileserver. Dir took 92 seconds, and my Filescan class only
took 72 seconds.

I also prefer the ordering of the output of my Filescan class.

Could you post your Filescan class?

I’d like to see it, and compare w/ find.rb in the standard distribution.

Jason Creighton

···

On Thu, 18 Sep 2003 15:59:25 +0100 Alan Davies NOSPAMcs96and@yahoo.co.ukNOSPAM wrote:

Weirich, James wrote:

I like the Dir form (or its “glob” alternative). I used to write
recursive functions to search a directory tree. Then I discovered
Dir[‘**/*.rb’]. Not only is it easier, it’s also faster.

I’m not so sure. I timed my recursive “Filescan” class against Dir on
a large fileserver. Dir took 92 seconds, and my Filescan class only
took 72 seconds.

I also prefer the ordering of the output of my Filescan class.

Could you post your Filescan class?

I’d like to see it, and compare w/ find.rb in the standard distribution.

Attatched. Its faster at most things than Dir#. I think the reason
it is faster is because it never actually changes the working directory.

To use it, e.g.:

require “Filescan”
File.open(“out.txt”, ‘w’) do |file|
Filescan.new(“c:/”).each { |name| file.puts name if name =~ /.mp3$/i}
end

There are also functions each_filename, each_file, each_dirname, each_dir.

each_line can also be used to seach through indvidual lines of text
files. It can also be used for search and replace.

filescan.rb (3.4 KB)

Attatched. Its faster at most things than Dir#. I think the reason
it is faster is because it never actually changes the working directory.

And again. This one has much faster implementations of each_filename
and each_dirname, by doing the regexp before doing the file/directory test.

filescan.rb (3.4 KB)

Change this

   @@dotDir = /^\.\.?$/

You can have a file (or a directory) with \n in the name

Guy Decoux

ts wrote:

“A” == Alan Davies NOSPAMcs96and@yahoo.co.ukNOSPAM writes:

Change this

@@dotDir = /^..?$/

You can have a file (or a directory) with \n in the name

Guy Decoux

I’m not sure what you’re getting at.

I’m pretty sure you can’t have filenames with \n in them, and that
pattern wouldn’t match them anyway.

I'm pretty sure you can't have filenames with \n in them, and that
pattern wouldn't match them anyway.

Then test it with a real OS :slight_smile:

svg% ls -a
./ ../
svg%

svg% ruby -e 'Dir.mkdir "aa\n.."'
svg%

svg% ls -a
./ ../ aa?../
svg%

svg% ruby -e 'Dir.foreach(".") {|d| p d}'
"."
".."
"aa\n.."
svg%

svg% ruby -e 'Dir.foreach(".") {|d| next if d =~ /^\.\.?$/; p d}'
svg%

Guy Decoux

ts wrote:

“A” == Alan Davies NOSPAMcs96and@yahoo.co.ukNOSPAM writes:

I’m pretty sure you can’t have filenames with \n in them, and that
pattern wouldn’t match them anyway.

Then test it with a real OS :slight_smile:

Personally I can’t stand linux/unix, but each to his own, as they say.

svg% ls -a
/ …/
svg%

svg% ruby -e ‘Dir.mkdir “aa\n…”’
svg%

svg% ls -a
/ …/ aa?../
svg%

svg% ruby -e ‘Dir.foreach(“.”) {|d| p d}’
“.”
“…”
“aa\n…”
svg%

svg% ruby -e ‘Dir.foreach(“.”) {|d| next if d =~ /^..?$/; p d}’
svg%

Guy Decoux

Filenames with \n in them is the most ridiculous thing I’ve ever heard.

I take it the regexp should be /\A..?\z/ then?

Alan.

Filenames with \n in them is the most ridiculous thing I've ever heard.

:slight_smile:

I take it the regexp should be /\A\.\.?\z/ then?

or you can do like in lib/find.rb

svg% grep 'next if' lib/find.rb
                next if f == "." or f == ".."
svg%

Guy Decoux

ts wrote:

            next if f == "." or f == ".."

I did used to do that. I can’t even remember why I changed it to a regexp!

Come on, you can’t resist.

class Object
def in?(enum)
enum.include?(self)
end
end


next if f.in? [“.”, “…”]

Isn’t that much nicer? :wink:

Gavin

···

On Wednesday, September 24, 2003, 12:33:54 AM, Alan wrote:

ts wrote:

            next if f == "." or f == ".."

I did used to do that. I can’t even remember why I changed it to a regexp!

ts wrote:

            next if f == "." or f == ".."

I did used to do that. I can’t even remember why I changed it to a regexp!

Come on, you can’t resist.

class Object
def in?(enum)
enum.include?(self)
end
end


next if f.in? [“.”, “…”]

or
next if %w{. …}.include? f

but personally i prefer this:

next if f =~ /^..?$/

···
  • Gavin Sinclair (gsinclair@soyabean.com.au) wrote:

On Wednesday, September 24, 2003, 12:33:54 AM, Alan wrote:

Isn’t that much nicer? :wink:

Gavin


Paul Duncan pabs@pablotron.org pabs in #gah (OPN IRC)
http://www.pablotron.org/ OpenPGP Key ID: 0x82C29562

Hi –

ts wrote:

            next if f == "." or f == ".."

I did used to do that. I can’t even remember why I changed it to a regexp!

Come on, you can’t resist.

class Object
def in?(enum)
enum.include?(self)
end
end


next if f.in? [“.”, “…”]

or
next if %w{. …}.include? f

but personally i prefer this:

next if f =~ /^..?$/

However…

$ ruby -e ‘File.new(“abc\n…\ndef”,“w”)’
$ ruby -e 'Dir[“abc*”].each {|f|

puts “#{f}: yes” if /^..?$/.match(f)}’
abc

def: yes

I know, I know, not likely :slight_smile: Still, /\A..?\z/ would be safer.

David

···

On Tue, 30 Sep 2003, Paul Duncan wrote:

  • Gavin Sinclair (gsinclair@soyabean.com.au) wrote:

On Wednesday, September 24, 2003, 12:33:54 AM, Alan wrote:


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav