6

i need a recursive function to list files in a folder:

def procdir(dirname)
  data = ''
  Dir.foreach(dirname) do |dir|
    dirpath = dirname + '/' + dir
    if File.directory?(dirpath) then
      if dir != '.' && dir != '..' then
        #puts "DIRECTORY: #{dirpath}" ; 
        procdir(dirpath)
      end
    else
      data += dirpath
    end
  end
  return data
end

but the result: is null

2

5 Answers 5

21

Stdlib Dir#glob recurses when you give it the ** glob.

def procdir(dir)
  Dir[ File.join(dir, '**', '*') ].reject { |p| File.directory? p }
end
Sign up to request clarification or add additional context in comments.

2 Comments

Thank for your responses, i understand my problem. dbenhur, your code is great! here is my code if it can help someone def procdir(dir) Dir[ File.join(dir, '*', '') ].reject { |p| File.directory? p } end file = procdir('mypath') #puts file file.each do |filename| #puts filename test = filename.scan(/SomeRegex/).flatten puts test (..) end Thank you all
Nice this is exactly what I was looking for
8

Use the find module:

require 'find'

pathes = []
Find.find('.') do |path|
  pathes << path unless FileTest.directory?(path)
end

puts pathes.inspect

Comments

7

Old thread but perhaps someone might find it useful:

array_of_all_files = Dir .glob("**/*") .reject { |file_path| File.directory? file_path }

7 Comments

Why did you repeat an answer nearly identical to the one I posted eight months earlier? Dir::[] is the same as Dir.glob. File.join('**', '*') is a more portable way to say "**/*".
I am sorry, I didn't know they were identical. And I felt this was more readable (probably, since I used it a bunch of times and never knew another representation of it).
@dbenhur : Just curious, why would File.join('**', '*') be more portable than "**/*". It works on Linux/Windows/MacOs as far as I know.
@EricDuminil Because there are more operating systems than that. File::join will join on File::SEPARATOR and not assume the underlying OS understands /.
@dbenhur: I agree that it can be a problem when using those paths with other programs. But File.join doesn't change anything : File.join("a","b") is "a/b", even on Windows.
|
1

It looks like there are a couple of problems with the recursion:

  • The else clause appears to associated with the wrong if. It needs to be associated with the first if.
  • The result of the recursive procdir call should be added to data.

If you indent the code a little more cleanly, it would probably be easier to spot problems like that. The following contains the two fixes:

def procdir(dirname)
  data = ''
  Dir.foreach(dirname) do |dir|
    dirpath = dirname + '/' + dir
    if File.directory?(dirpath) then
      if dir != '.' && dir != '..' then
        #puts "DIRECTORY: #{dirpath}" ; 
        data += procdir(dirpath)
      end
    else
      data += dirpath
    end
  end
  return data
end

1 Comment

Thank for your responses, i understand my problem.
0

If you know the file extensions you will have just use this:

Dir[Rails.root.join('config/locales/**/*.{rb,yml}')]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.