Ruby File::directory? Проблемы

Поиск C#:

Ничто для вычисления действительно просто ищите его. Для расширения его добавьте еще 8 чисел к таблице, и целые числа на 64 бита в в их пределе. Кроме того, класс BigNum требуется.

public static int Factorial(int f)
{ 
    if (f<0 || f>12)
    {
        throw new ArgumentException("Out of range for integer factorial");
    }
    int [] fact={1,1,2,6,24,120,720,5040,40320,362880,3628800,
                 39916800,479001600};
    return fact[f];
}
15
задан 17 November 2009 в 06:06
поделиться

4 ответа

Вы выполняете сценарий из / tmp ? Я предполагаю (я этого не пробовал), что File.directory? (X) проверяет, есть ли в текущем каталоге каталог с именем x - так что, если вы запускаете это из другой каталог, вы всегда найдете . и .. но не другие каталоги.

Попробуйте изменить File.directory? (x) на File.directory? ("# {path} / # {x}") .

17
ответ дан 1 December 2019 в 02:46
поделиться

Я внес несколько незначительных изменений ...

class Directory < Dir
  def subdirs
    subdirs = []
    each do |x|
      puts "Evaluating file: #{x}"
      if File.directory? File.join path, x
        puts "This file (#{x}) was considered a directory by File.directory?"
        subdirs << x
        #yield(x) if block_given?
      end
    end
    subdirs
  end
end
puts "Testing new Directory custom class: FileOps/DirClass"

nd   = Directory.new "/tmp"
puts subs = nd.subdirs
0
ответ дан 1 December 2019 в 02:46
поделиться

Замените * любым путем, который хотите, и все готово. Glob получает все файлы по некоторому пути, используя подстановку bash, поэтому вы можете использовать * и **, а также диапазоны и т. Д. Довольно мило.

Выбор работает как противоположность reject, выбирая только те значения, которые являются истина внутри блока выбора.

Dir.glob ("*"). select {| f | File.directory?(f)}

0
ответ дан 1 December 2019 в 02:46
поделиться

Марк Вестлинг уже ответил на ваш непосредственный вопрос, но, поскольку вы упомянули, что вы новичок в Ruby, здесь есть пара других предложений по стилю:

def subdirs
  subdirs = Array.new

Обычно предпочтительно использовать буквальный синтаксис там, где это возможно, поэтому общий способ выразить это будет subdirs = [] .

  self.each do |x|

self is неявный получатель в Ruby, так что вы можете просто отключить его. (В конце концов, это не Python.) Однако основная цель кода - коммуникация, поэтому, если вы считаете, что это лучше передает ваши намерения, оставьте это.

Говоря о коммуникации: x это не очень коммуникативное имя, если вы не говорите о точках в декартовой системе координат. Как насчет файла , или, если вас не устраивает представление Unix о том, что каталоги также являются файлами, более нейтральная запись ? (На самом деле, лучшим вариантом, вероятно, будет path , но мы скоро увидим, как это может сбивать с толку.)

Мое третье предложение на самом деле является личным предпочтением, которое противоречит общему стилю Ruby: общий стиль Ruby диктует, что однострочные блоки разделяются { / } , а многострочные блоки - do / end , как и вы. . Мне это не нравится, потому что это произвольное различие, которое не передает никакого значения . (Помните, что такое «общение»?) Итак, на самом деле я делаю все по-другому: если блок является императивным по своей природе и, например, изменяет какое-то глобальное состояние, я использую ключевые слова (потому что блок фактически выполняет некоторую работу), и если блок является функциональным по своей природе и просто возвращает новый объект, я предпочитаю использовать фигурные скобки (потому что они выглядят красиво математически). Итак, в этом случае я бы использовал фигурные скобки.

    if File.directory?(x)

Как уже объяснил Марк, вам нужно сделать что-то вроде File.directory? (File.join (path, entry)) здесь, где ] Dir # path - это открытый атрибут класса Dir , возвращающий путь, которым был инициализирован Dir.new .

Здесь вы также видите, почему мы этого не сделали » t используйте путь в качестве имени параметра блока. В противном случае нам нужно было бы написать File.directory? (File.join (self.path, path)) .

      subdirs.push(x)

Канонический способ добавить элемент к массиву или практически что угодно к чему-либо в Ruby - это оператор << . Таким образом, это должно выглядеть так: subdirs << entry .

Array # push - это псевдоним Array # << , который в основном предназначен для использования Массив как стек (в сочетании с Array # pop ).

    end
  end
  return subdirs

Вот еще одно несоответствие между моим личным стилем и общим стилем Ruby: в Ruby, если нет явного return , возвращаемое значение - это просто значение последнего выражения. Это означает, что вы можете не использовать ключевое слово return , и общий стиль Ruby говорит, что вы должны это делать. Однако я предпочитаю использовать это подобно разделителям блоков: используйте return для методов, которые являются функциональными по своей природе (потому что они фактически «возвращают» значение) и не return для императивных методов (потому что их реальное возвращаемое значение равно не то, что следует после ключевого слова return , а то, какие побочные эффекты они оказывают на среду). Итак, как и вы, я бы использовал здесь ключевое слово return , несмотря на общий стиль.

Также принято отделять возвращаемое значение от остальной части тела метода пустой строкой. (Кстати, то же самое касается кода установки.)

end

Итак, вот где мы находимся прямо сейчас:

def subdirs
  subdirs = []

  each { |entry|
    if File.directory?(File.join(path, entry))
      subdirs << entry
    end
  }

  return subdirs
end

Как видите, выражение if действительно служит только для пропуска одной итерации. петли. Это гораздо лучше передать с помощью ключевого слова next :

def subdirs
  subdirs = []

  each { |entry|
    next  unless File.directory?(File.join(path, entry))
    subdirs << entry
  }

  return subdirs
end

Как видите, рано возвращается из метода, пропускает одну итерацию цикла, ...). В Ruby для этого можно использовать raise , return , next и break . На других языках даже GOTO в порядке (это один из тех редких случаев, когда GOTO может фактически очистить поток управления ).

Однако , мы можем упростить это еще больше, распознав шаблон итератора: вы берете список (записи каталога), а затем «сжимаете» этот список до одного объекта (массив subdirs ). Для теоретика категорий это кричит «катаморфизм», для хардкорного функционального программиста « фолд », для софткорного функционального программиста « уменьшить », для Smalltalk-программиста » )

Последнее, что мы можем сделать, - это признать, что то, что мы делаем, - это просто фильтрация (или, другими словами, «выбор») элементов массива. А в Ruby уже есть встроенный метод, который делает именно это: Enumerable # select . Обратите внимание на удивительные возможности однострочного языка, которые дает использование всей мощи Ruby:

def subdirs
  return select { |entry| File.directory?(File.join(path, entry)) }
end

В качестве общего совета: изучите чудеса Enumerable . Это рабочая лошадка программирования на Ruby, похожая на IEnumerable в .NET, dict s в Python, списки на функциональных языках или ассоциативные массивы в PHP. и Perl.

Обратите внимание на удивительные возможности однострочного языка, которые создает использование всей мощи Ruby:

def subdirs
  return select { |entry| File.directory?(File.join(path, entry)) }
end

В качестве общего совета: изучите чудеса Enumerable . Это рабочая лошадка программирования на Ruby, похожая на IEnumerable в .NET, dict s в Python, списки на функциональных языках или ассоциативные массивы в PHP. и Perl.

Обратите внимание на удивительные возможности однострочного языка, которые создает использование всей мощи Ruby:

def subdirs
  return select { |entry| File.directory?(File.join(path, entry)) }
end

В качестве общего совета: изучите чудеса Enumerable . Это рабочая лошадка программирования на Ruby, похожая на IEnumerable в .NET, dict s в Python, списки на функциональных языках или ассоциативные массивы в PHP. и Perl.

9
ответ дан 1 December 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: