Что причины там для предпочтения шарика по readdir (или наоборот) в Perl?

не уверенный, если, что, что Вы спрашиваете, но можно расширить существующие типы и затем назвать то, что Вы любите на новой вещи:

class  int(int):
     def random_method(self):
           return 4                     # guaranteed to be random
v = int(5)                              # you'll have to instantiate all you variables like this
v.random_method()

class int(int):
    def xkcd(self):
        import antigravity
        print(42)

>>>v.xkcd()
Traceback (most recent call last):
  File "<pyshell#81>", line 1, in <module>
    v.xkcd()
AttributeError: 'int' object has no attribute 'xkcd'
c = int(1)
>>> c.random_method()
4
>>> c.xkcd()
42

надежда, которая разъясняет Ваш вопрос

62
задан 14 revs, 4 users 83% 23 May 2017 в 11:53
поделиться

8 ответов

Вы пропустили самое важное, самое большое различие между ними: glob возвращает вам список, а opendir дает вам дескриптор каталога. Вы можете передать этот дескриптор каталога, чтобы позволить другим объектам или подпрограммам использовать его. С дескриптором каталога подпрограмме или объекту не нужно ничего знать о том, откуда он пришел, кто еще его использует и т. Д.

 sub use_any_dir_handle {
      my( $dh ) = @_;
      rewinddir $dh;
      ...do some filtering...
      return \@files;
      }

С помощью дескриптора dir у вас есть управляемый итератор, по которому вы можете перемещаться с помощью seekdir , хотя с glob вы просто получаете следующий элемент.

Однако, как и в любом другом случае, затраты и выгоды имеют смысл только при применении к определенному контексту. Они не существуют вне определенного использования. У вас есть отличный список их различий, но я бы не стал t классифицируйте эти различия, не зная, что вы пытались с ними сделать.

Еще кое-что, о чем следует помнить:

  • Вы можете реализовать свой собственный глобус с помощью opendir , но не наоборот.

  • glob использует собственный синтаксис подстановочных знаков, и это все, что у вас есть.

  • glob может возвращать несуществующие имена файлов:

     $ perl -le 'print glob "{ab} {cd}"'
    
43
ответ дан 24 November 2019 в 16:52
поделиться

glob pro: Может возвращать несуществующие «имена файлов»:

my @deck = List::Util::shuffle glob "{A,K,Q,J,10,9,8,7,6,5,4,3,2}{\x{2660},\x{2665},\x{2666},\x{2663}}";
while (my @hand = splice @deck,0,13) {
    say join ",", @hand;
}
__END__
6♥,8♠,7♠,Q♠,K♣,Q♦,A♣,3♦,6♦,5♥,10♣,Q♣,2♠
2♥,2♣,K♥,A♥,8♦,6♠,8♣,10♠,10♥,5♣,3♥,Q♥,K♦
5♠,5♦,J♣,J♥,J♦,9♠,2♦,8♥,9♣,4♥,10♦,6♣,3♠
3♣,A♦,K♠,4♦,7♣,4♣,A♠,4♠,7♥,J♠,9♥,7♦,9♦
8
ответ дан 24 November 2019 в 16:52
поделиться

Ну, вы в значительной степени прикрыли это. Принимая во внимание все это, я бы предпочел использовать glob , когда я создаю быстрый одноразовый скрипт, и его поведение является именно тем, что я хочу, и использую opendir и readdir в текущем производственном коде или библиотеках, где я могу не торопиться и более ясный, более чистый код полезен.

4
ответ дан 24 November 2019 в 16:52
поделиться

Для небольших простых вещей я предпочитаю glob . Буквально на днях я использовал его вместе с Perl-скриптом из двадцати строк, чтобы изменить теги большой части моей музыкальной библиотеки. glob , однако, имеет довольно странное имя. Глоб? Это совсем не интуитивно понятно, если говорить о названии.

Моя самая большая проблема с readdir заключается в том, что он обращается с каталогом способом, который несколько странен для большинства людей. Обычно программисты не думают о каталоге как о потоке, они думают о нем как о ресурсе или списке, который предоставляет glob. Название лучше, функциональность лучше, но интерфейс все же оставляет желать лучшего.

3
ответ дан 24 November 2019 в 16:52
поделиться

Это был довольно полный список. readdir readdir + grep ) имеет меньше накладных расходов, чем glob , и это плюс для readdir если вам нужно проанализировать очень много каталогов.

2
ответ дан 24 November 2019 в 16:52
поделиться

glob pros:

3) Нет необходимости добавлять имя каталога к элементам вручную

Исключение:

say for glob "*";

--output:--
1perl.pl
2perl.pl
2perl.pl.bak
3perl.pl
3perl.pl.bak
4perl.pl
data.txt
data1.txt
data2.txt
data2.txt.out

Насколько я могу судить, правило для glob таково: вы должны указать полный путь к каталог, чтобы получить обратно полные пути. Документы Perl, похоже, не упоминают об этом, как и никакие другие сообщения здесь.

Это означает, что glob можно использовать вместо readdir , когда вам нужны только имена файлов (а не полные пути), и вы не хотите, чтобы возвращались скрытые файлы, т.е. начиная с '.'. Например,

chdir ("../..");  
say for glob("*");
2
ответ дан 24 November 2019 в 16:52
поделиться

glob позволяет удобно читать все подкаталоги заданной фиксированной глубины, как в glob "* / * / *" . Я несколько раз находил это удобным.

5
ответ дан 24 November 2019 в 16:52
поделиться

Вот недостаток для opendir и readdir.

{
  open my $file, '>', 0;
  print {$file} 'Breaks while( readdir ){ ... }'
}
opendir my $dir, '.';

my $a = 0;
++$a for readdir $dir;
print $a, "\n";

rewinddir $dir;

my $b = 0;
++$b while readdir $dir;
print $b, "\n";

Можно было бы ожидать, что код выведет одно и то же число дважды, но это не так, потому что существует файл с именем 0. На моем компьютере он печатает 251, и 188, проверено с Perl v5.10.0 и v5.10. 1

Эта проблема также делает так, что он просто печатает кучу пустых строк, независимо от существования файла 0:

use 5.10.0;
opendir my $dir, '.';

say while readdir $dir;

В то время как это всегда работает просто отлично:

use 5.10.0;
my $a = 0;
++$a for glob '*';
say $a;

my $b = 0;
++$b while glob '*';
say $b;

say for glob '*';
say while glob '*';

Я исправил эти проблемы и послал патч, который вошел в Perl v5.11.2, так что это будет правильно работать с Perl v5.12.0, когда он выйдет.

Мое исправление преобразует this:

while( readdir $dir ){ ... }

в this:

while( defined( $_ = readdir $dir ){ ...}

Что заставляет его работать так же, как read работал с файлами. На самом деле это тот же самый кусок кода, я просто добавил еще один элемент к соответствующим if утверждениям.

6
ответ дан 24 November 2019 в 16:52
поделиться
Другие вопросы по тегам:

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