I'm learning Ruby, but I'm having trouble with the whole implicit return value thing. Someone please tell me why this returns an empty vector:
3 def get_filenames(path)
4 filenames = []
5
6 if (path == ".") || (path == "..")
7 []
8 elsif File.directory? path
9 Dir.entrie开发者_StackOverflow社区s(path).each do |sub_path|
10 filenames += get_filenames(sub_path)
11 end
12 else #presumably it's a file
13 [File.basename(path,".*")]
14 end
15 end
It should be returning an array of all file names (sans their extension) found when recursively searching from the argument path.
Assume that I call the function with "/tmp" and tmp contains 2 files: "A.txt" and "B.m" and then a directory which contains 1 file "C.exe". I want this function to return ["A","B","C"]
first of all, Dir.entries
does not get absolute paths, so when you try calling get_filenames(sub_path)
you call for a relative filename path (and your function receives an absolute path)
use this:
def get_files(dir)
files = []
Find.find(dir) { |path| files << File.basename(path,".*") if FileTest.file?(path) }
return files
end
Here's a simple solution to your query... Find every file present in the current directory and sub-directories
{Find.find("", "#{path}") do |file|
if File.file?(file)
filenames << file.to_s
end
end
}
Your if statement has three paths; the first returns an empty array, and the last returns a single element wrapped in an array. So far so good.
But the middle path returns the value of Dir.entries
, which itself returns all the entries for the folder identified by path
. The each
iterator produces the side effect of recursively calling get_filenames
and appending them to the local variable filenames
, but the return value of Dir.entries
is not affected by this -- it still returns all the entries in the folder.
To get the result you want, just add filenames
after the Dir.entries call.
It is finding your if
statement to be true, I believe, causing it to exit on the first pass through. What happens if you remove that portion of the logic (move elseif
to if
so you just have if
and else
?
This works on my machine as expected.
Try adding print statements in the argument and each one of the returned values to see what is actually happening in your case.
It is possible that your think you're passing one value when in fact you're passing another.
精彩评论