Изучение Ruby: возвращаемое значение - PullRequest
0 голосов
/ 17 января 2011

Я изучаю Ruby, но у меня проблемы с неявным возвратом значений. Кто-то, пожалуйста, скажите мне, почему это возвращает пустой вектор:

  3 def get_filenames(path)
  4   filenames = []
  5 
  6   if (path == ".") || (path == "..")
  7     []
  8   elsif File.directory? path
  9     Dir.entries(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

Он должен возвращать массив всех имен файлов (без их расширения), найденных при рекурсивном поиске по пути аргумента.

Предположим, что я вызываю функцию с "/ tmp", и tmp содержит 2 файла: "A.txt" и "B.m", а затем каталог, который содержит 1 файл "C.exe". Я хочу, чтобы эта функция возвращала ["A", "B", "C"]

Ответы [ 5 ]

2 голосов
/ 17 января 2011

Прежде всего, Dir.entries не получает абсолютные пути, поэтому, когда вы пытаетесь вызвать get_filenames(sub_path), вы вызываете относительный путь к файлу (а ваша функция получает абсолютный путь)

используйте это:1005 *

def get_files(dir)
   files = []
   Find.find(dir) { |path| files << File.basename(path,".*") if FileTest.file?(path) }
   return files
end
1 голос
/ 17 января 2011

Ваш оператор if имеет три пути; первый возвращает пустой массив, а последний возвращает один элемент, заключенный в массив. Пока все хорошо.

Но средний путь возвращает значение Dir.entries, которое само возвращает все записи для папки, обозначенной path. Итератор each создает побочный эффект рекурсивного вызова get_filenames и добавления их к локальной переменной filenames, но на возвращаемое значение Dir.entries это не влияет - он по-прежнему возвращает все записи в папке .

Чтобы получить желаемый результат, просто добавьте filenames после вызова Dir.entries.

1 голос
/ 17 января 2011

Вот простое решение вашего запроса ... Найти каждый файл в текущем каталоге и подкаталогах

{Find.find("", "#{path}") do |file|
 if File.file?(file)
   filenames << file.to_s
 end
end
}
0 голосов
/ 17 января 2011

Это работает на моей машине, как и ожидалось.

Попробуйте добавить операторы print в аргумент и каждое из возвращаемых значений, чтобы увидеть, что на самом деле происходит в вашем случае.

Возможно, вы думаете, что вы передаете одно значение, а на самом деле вы передаете другое.

0 голосов
/ 17 января 2011

Я считаю, что ваше утверждение if соответствует действительности, что заставляет его завершиться при первом проходе.Что произойдет, если вы удалите эту часть логики (переместите elseif в if, чтобы у вас просто были if и else?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...