[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to Traverse a Directory

Greg Chagnon

9/21/2006 9:06:00 AM

def traverse(root)
Dir.foreach(root) do |file|
next if file[0] == ?.
puts file
traverse(root + '\\' + file) if File.directory?(root + '\\' + file)
end
end

This is my initial attempt. Two things feel rather wrong:
1) Is there a simpler way to test the beginning of a string? A startsWith?(aString) like method?
2) I'm iterating through filenames, then appending the path each time. Is there a way to get a
collection of File objects from a directory?

Any other pointers to where I could improve would also be greatly appreciated.

(I tried posting this twice through Teranews, but it doesn't seem to have got through.)
6 Answers

Marc Heiler

9/21/2006 9:40:00 AM

0

Cant really help you but just want to say that
next if file[0] == ?.

is something I did too to get rid of the . and .. which
dont really give me helpful info (when i look for real
files or directories for example)

--
Posted via http://www.ruby-....

MonkeeSage

9/21/2006 9:46:00 AM

0

Newbie wrote:
> def traverse(root)
> Dir.foreach(root) do |file|

You can use Dir #[], #glob, or #entries also. If you use a glob or the
entries method, you can also automatically skip the . and .. --
Dir.entries(root)[2..-1] will give you an array of all the files and
subdirs in root, minus the first two (which are always . and ..) If you
do that, you can skip the next line.

Check out the docs to see how to use them further:
http://ruby-doc.org/core/classe...

> next if file[0] == ?.

This will probably work for most cases in windows (though not always),
but it definitely a bad idea for any other OS (because filenames can
start with a . to mean they should be hidden in normal listing modes).
What I usually use is -- next if ['.', '..'].include? file -- which
checks if the full filename == '.' or '..'

> puts file
> traverse(root + '\\' + file) if File.directory?(root + '\\' + file)

This is also not very portable. Better to use File.join(root, file)

> end
> end

Ps. Your directory traverser looks ALOT better than my first one did!

HTH,
Jordan

MonkeeSage

9/21/2006 9:52:00 AM

0


MonkeeSage wrote:
> > puts file
> > traverse(root + '\\' + file) if File.directory?(root + '\\' + file)
>
> This is also not very portable. Better to use File.join(root, file)

You can also refactor that to this:

puts file = File.join(root, file) # assignment returns its value
traverse(file) if File.directory?(file)

Robert Klemme

9/21/2006 10:08:00 AM

0

On 21.09.2006 11:06, Newbie wrote:
> def traverse(root)
> Dir.foreach(root) do |file|
> next if file[0] == ?.
> puts file
> traverse(root + '\\' + file) if File.directory?(root + '\\' + file)
> end
> end
>
> This is my initial attempt. Two things feel rather wrong:
> 1) Is there a simpler way to test the beginning of a string? A
> startsWith?(aString) like method?

Like this?
next if /^\./ =~ file

> 2) I'm iterating through filenames, then appending the path each time.
> Is there a way to get a collection of File objects from a directory?

File objects are for actually reading and writing objects. You can do
Dir["*"] which returns an array of strings.

> Any other pointers to where I could improve would also be greatly
> appreciated.

Use Find:

irb(main):001:0> require 'find'
=> true
irb(main):002:0> Find.find('.') {|f| puts f}
.
../x
../prj-jar.txt
../jdk-jar.txt
=> nil

irb(main):005:0> Find.find('/tmp') {|f| puts f}
/tmp
/tmp/x
/tmp/prj-jar.txt
/tmp/jdk-jar.txt
=> nil

irb(main):008:0> Find.find '/tmp' do |f|
irb(main):009:1* next if File.directory? f
irb(main):010:1> puts f
irb(main):011:1> end
/tmp/x
/tmp/prj-jar.txt
/tmp/jdk-jar.txt

Note, you can also use File.join to portably combine paths.

Kind regards

robert

Greg Chagnon

9/21/2006 10:19:00 AM

0

Thanks for all the help!

MonkeeSage wrote:
<stuff>

Greg Chagnon

9/21/2006 5:07:00 PM

0

MonkeeSage wrote:
>> next if file[0] == ?.
>
> This will probably work for most cases in windows (though not always),
> but it definitely a bad idea for any other OS (because filenames can
> start with a . to mean they should be hidden in normal listing modes).
> What I usually use is -- next if ['.', '..'].include? file -- which
> checks if the full filename == '.' or '..'

Good point - perhaps http://www.ruby-doc.org/core/classes... should be fixed ;-)