Aion-Fs

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

```perl
use Aion::Fs;

lay mkpath "hello/world.txt", "hi!";
lay mkpath "hello/moon.txt", "noreplace";
lay mkpath "hello/big/world.txt", "hellow!";
lay mkpath "hello/small/world.txt", "noenter";

mtime "hello";  # ~> ^\d+(\.\d+)?$

[map cat, grep -f, find ["hello/big", "hello/small"]];  # --> [qw/ hellow! noenter /]

my @noreplaced = replace { s/h/$a $b H/ }
    find "hello", "-f", "*.txt", qr/\.txt$/, sub { /\.txt$/ },
        noenter "*small*",
            errorenter { warn "find $_: $!" };

\@noreplaced; # --> ["hello/moon.txt"]

cat "hello/world.txt";       # => hello/world.txt :utf8 Hi!
cat "hello/moon.txt";        # => noreplace

README.md  view on Meta::CPAN


my $count = 0;
find "ex", sub { find_stop if ++$count == 3; 1};
$count # -> 3
```

### See also

* [AudioFile::Find](https://metacpan.org/pod/AudioFile::Find) – ищет аудиофайлы в указанной директории. Позволяет фильтровать их по атрибутам: названию, артисту, жа...
* [Directory::Iterator](https://metacpan.org/pod/Directory::Iterator) – `$it = Directory::Iterator->new($dir, %opts); push @paths, $_ while <$it>`.
* [IO::All](https://metacpan.org/pod/IO::All) – `@paths = map { "$_" } grep { -f $_ && $_->size > 10*1024 } io(".")->all(0)`.
* [IO::All::Rule](https://metacpan.org/pod/IO::All::Rule) – `$next = IO::All::Rule->new->file->size(">10k")->iter($dir1, $dir2); push @paths, "$f" while $f = $next->()`.
* [File::Find](https://metacpan.org/pod/File::Find) – `find( sub { push @paths, $File::Find::name if /\.png/ }, $dir )`.
* [File::Find::utf8](https://metacpan.org/pod/File::Find::utf8) – как [File::Find](https://metacpan.org/pod/File::Find), только пути файлов в _utf8_.
* [File::Find::Age](https://metacpan.org/pod/File::Find::Age) – сортирует файлы по времени модификации (наследует [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule)): `File::Find::Age->in($dir1,...
* [File::Find::Declare](https://metacpan.org/pod/File::Find::Declare) – `@paths = File::Find::Declare->new({ size => '>10K', perms => 'wr-wr-wr-', modified => '<2010-01-30', recurse => 1, dirs => [$dir1] })->find`.
* [File::Find::Iterator](https://metacpan.org/pod/File::Find::Iterator) – имеет ООП интерфейс с итератором и функции `imap` и `igrep`.
* [File::Find::Match](https://metacpan.org/pod/File::Find::Match) – вызывает обработчик на каждый подошедший фильтр. Похож на `switch`.
* [File::Find::Node](https://metacpan.org/pod/File::Find::Node) – обходит иерархию файлов параллельно несколькими процессами: `tie @paths, IPC::Shareable, { key => "GLUE STRING", create => 1 }; F...
* [File::Find::Fast](https://metacpan.org/pod/File::Find::Fast) – `@paths = @{ find($dir) }`.
* [File::Find::Object](https://metacpan.org/pod/File::Find::Object) – имеет ООП интерфейс с итератором.
* [File::Find::Parallel](https://metacpan.org/pod/File::Find::Parallel) – умеет сравнивать два каталога и возвращать их объединение, пересечение и количественное перес...
* [File::Find::Random](https://metacpan.org/pod/File::Find::Random) – выбирает файл или директорию наугад из иерархии файлов.
* [File::Find::Rex](https://metacpan.org/pod/File::Find::Rex) – `@paths = File::Find::Rex->new(recursive => 1, ignore_hidden => 1)->query($dir, qr/^b/i)`.
* [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule) – `@files = File::Find::Rule->any( File::Find::Rule->file->name('*.mp3', '*.ogg')->size('>2M'), File::Find::Rule->empty )->in($dir1, $dir2);`. Имеет итератор, процед...
* [File::Find::Wanted](https://metacpan.org/pod/File::Find::Wanted) – `@paths = find_wanted( sub { -f && /\.png/ }, $dir )`.
* [File::Hotfolder](https://metacpan.org/pod/File::Hotfolder) – `watch( $dir, callback => sub { push @paths, shift } )->loop`. Работает на `AnyEvent`. Настраиваемый. Есть распараллеливание на неско...
* [File::Mirror](https://metacpan.org/pod/File::Mirror) – формирует так же параллельный путь для копирования файлов: `recursive { my ($src, $dst) = @_; push @paths, $src } '/path/A', '/path/B'`.
* [File::Set](https://metacpan.org/pod/File::Set) – `$fs = File::Set->new; $fs->add($dir); @paths = map { $_->[0] } $fs->get_path_list`.
* [File::Wildcard](https://metacpan.org/pod/File::Wildcard) – `$fw = File::Wildcard->new(exclude => qr/.svn/, case_insensitive => 1, sort => 1, path => "src///*.cpp", match => qr(^src/(.*?)\.cpp$), derive => ['src/$1.o','src/$1.hpp']); push @paths,...
* [File::Wildcard::Find](https://metacpan.org/pod/File::Wildcard::Find) – `findbegin($dir); push @paths, $f while $f = findnext()` или  `findbegin($dir); @paths = findall()`.
* [File::Util](https://metacpan.org/pod/File::Util) – `File::Util->new->list_dir($dir, qw/ --pattern=\.txt$ --files-only --recurse /)`.
* [Mojo::File](https://metacpan.org/pod/Mojo::File) – `say for path($path)->list_tree({hidden => 1, dir => 1})->each`.
* [Path::Find](https://metacpan.org/pod/Path::Find) – `@paths = path_find( $dir, "*.png" )`. Для сложных запросов использует _matchable_: `my $sub = matchable( sub { my( $entry, $directory, $fullname, $depth ) = @_; $dep...
* [Path::Extended::Dir](https://metacpan.org/pod/Path::Extended::Dir) – `@paths = Path::Extended::Dir->new($dir)->find('*.txt')`.
* [Path::Iterator::Rule](https://metacpan.org/pod/Path::Iterator::Rule) – `$i = Path::Iterator::Rule->new->file; @paths = $i->clone->size(">10k")->all(@dirs); $i->size("<10k")...`.
* [Path::Class::Each](https://metacpan.org/pod/Path::Class::Each) – `dir($dir)->each(sub { push @paths, "$_" })`.
* [Path::Class::Iterator](https://metacpan.org/pod/Path::Class::Iterator) – `$i = Path::Class::Iterator->new(root => $dir, depth => 2); until ($i->done) { push @paths, $i->next->stringify }`.
* [Path::Class::Rule](https://metacpan.org/pod/Path::Class::Rule) – `@paths = Path::Class::Rule->new->file->size(">10k")->all($dir)`.

README.md  view on Meta::CPAN

Файл lib/N.pm:
```perl
package N;
sub ex { 123 }
1;
```

```perl
use lib "lib";
include("A")->new               # ~> A=HASH\(0x\w+\)
[map include, qw/A N/]          # --> [qw/A N/]
{ local $_="N"; include->ex }   # -> 123
```

## catonce (;$file)

Считывает файл в первый раз. Любая последующая попытка считать этот файл возвращает `undef`. Используется для вставки модулей js и css в резулÑ...

* `$file` может содержать массивы из двух элементов. Первый рассматривается как путь, а второй – как слой. Слой по умолчанию – `:utf8`.
* Если `$file` не указан – использует `$_`.

README.md  view on Meta::CPAN


eval { goto_editor "`", 1 }; $@  # ~> `:1 --> 512
```

## from_pkg (;$pkg)

Переводит пакет в путь ФС. Без параметра использует `$_`.

```perl
from_pkg "Aion::Fs"  # => Aion/Fs.pm
[map from_pkg, "Aion::Fs", "A::B::C"]  # --> ["Aion/Fs.pm", "A/B/C.pm"]
```

## to_pkg (;$path)

Переводит путь из ФС в пакет. Без параметра использует `$_`.

```perl
to_pkg "Aion/Fs.pm"  # => Aion::Fs
[map to_pkg, "Aion/Fs.md", "A/B/C.md"]  # --> ["Aion::Fs", "A::B::C"]
```

## from_inc (;$pkg)

Переводит пакет в путь ФС в `@INC`. Файл с пакетом должен существовать в одном из путей `@INC`. Без параметра использует `$_`.

```perl
from_inc "Aion::Fs" # -> $INC{'Aion/Fs.pm'}
[map from_inc, "A::B::C", "Aion::Fs"]  # --> [$INC{'Aion/Fs.pm'}]

from_inc "A::B::C" # -> undef
```

## to_inc (;$path)

Переводит путь из ФС в `@INC` в пакет. Без параметра использует `$_`.

```perl
to_inc $INC{'Aion/Fs.pm'} # => Aion::Fs
[map to_inc,"A/B/C.pm", $INC{'Aion/Fs.pm'}]  # --> ["Aion::Fs"]

to_inc 'Aion/Fs.pm' # -> undef
```

## ilay (;$path)

Создаёт файловый дескриптор. Он умеет закрываться, как только на него исчезнет последняя ссылка.

Так же имеет метод `path`, к-й возвращает путь к файлу.

i18n/Aion/Fs.ru-en.po  view on Meta::CPAN


msgid "В этом примере `find` не может войти в подкаталог и передаёт ошибку в функцию `errorenter` (см. ниже) с установленными переменными `$_` и `$!` (путё...
msgstr "In this example, `find` cannot enter the subdirectory and passes an error to the `errorenter` function (see below) with the `$_` and `$!` variables set (to the directory path and the OS error message)."

msgid "**Внимание!** Если `errorenter` не указана, то все ошибки **игнорируются**!"
msgstr "**Attention!** If `errorenter` is not specified, then all errors are **ignored**!"

msgid ""
"* [AudioFile::Find](https://metacpan.org/pod/AudioFile::Find) – ищет аудиофайлы в указанной директории. Позволяет фильтровать их по атрибутам: названию, артисту, жÐ...
"* [Directory::Iterator](https://metacpan.org/pod/Directory::Iterator) – `$it = Directory::Iterator->new($dir, %opts); push @paths, $_ while <$it>`.\n"
"* [IO::All](https://metacpan.org/pod/IO::All) – `@paths = map { \"$_\" } grep { -f $_ && $_->size > 10*1024 } io(\".\")->all(0)`.\n"
"* [IO::All::Rule](https://metacpan.org/pod/IO::All::Rule) – `$next = IO::All::Rule->new->file->size(\">10k\")->iter($dir1, $dir2); push @paths, \"$f\" while $f = $next->()`.\n"
"* [File::Find](https://metacpan.org/pod/File::Find) – `find( sub { push @paths, $File::Find::name if /\\.png/ }, $dir )`.\n"
"* [File::Find::utf8](https://metacpan.org/pod/File::Find::utf8) – как [File::Find](https://metacpan.org/pod/File::Find), только пути файлов в _utf8_.\n"
"* [File::Find::Age](https://metacpan.org/pod/File::Find::Age) – сортирует файлы по времени модификации (наследует [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule)): `File::Find::Age->in($dir1...
"* [File::Find::Declare](https://metacpan.org/pod/File::Find::Declare) – `@paths = File::Find::Declare->new({ size => '>10K', perms => 'wr-wr-wr-', modified => '<2010-01-30', recurse => 1, dirs => [$dir1] })->find`.\n"
"* [File::Find::Iterator](https://metacpan.org/pod/File::Find::Iterator) – имеет ООП интерфейс с итератором и функции `imap` и `igrep`.\n"
"* [File::Find::Match](https://metacpan.org/pod/File::Find::Match) – вызывает обработчик на каждый подошедший фильтр. Похож на `switch`.\n"
"* [File::Find::Node](https://metacpan.org/pod/File::Find::Node) – обходит иерархию файлов параллельно несколькими процессами: `tie @paths, IPC::Shareable, { key => \"GLUE STRING\", create => 1 }...
"* [File::Find::Fast](https://metacpan.org/pod/File::Find::Fast) – `@paths = @{ find($dir) }`.\n"
"* [File::Find::Object](https://metacpan.org/pod/File::Find::Object) – имеет ООП интерфейс с итератором.\n"
"* [File::Find::Parallel](https://metacpan.org/pod/File::Find::Parallel) – умеет сравнивать два каталога и возвращать их объединение, пересечение и количественное переÑ...
"* [File::Find::Random](https://metacpan.org/pod/File::Find::Random) – выбирает файл или директорию наугад из иерархии файлов.\n"
"* [File::Find::Rex](https://metacpan.org/pod/File::Find::Rex) – `@paths = File::Find::Rex->new(recursive => 1, ignore_hidden => 1)->query($dir, qr/^b/i)`.\n"
"* [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule) – `@files = File::Find::Rule->any( File::Find::Rule->file->name('*.mp3', '*.ogg')->size('>2M'), File::Find::Rule->empty )->in($dir1, $dir2);`. Имеет итератор, процеÐ...
"* [File::Find::Wanted](https://metacpan.org/pod/File::Find::Wanted) – `@paths = find_wanted( sub { -f && /\\.png/ }, $dir )`.\n"
"* [File::Hotfolder](https://metacpan.org/pod/File::Hotfolder) – `watch( $dir, callback => sub { push @paths, shift } )->loop`. Работает на `AnyEvent`. Настраиваемый. Есть распараллеливание на нескÐ...
"* [File::Mirror](https://metacpan.org/pod/File::Mirror) – формирует так же параллельный путь для копирования файлов: `recursive { my ($src, $dst) = @_; push @paths, $src } '/path/A', '/path/B'`.\n"
"* [File::Set](https://metacpan.org/pod/File::Set) – `$fs = File::Set->new; $fs->add($dir); @paths = map { $_->[0] } $fs->get_path_list`.\n"
"* [File::Wildcard](https://metacpan.org/pod/File::Wildcard) – `$fw = File::Wildcard->new(exclude => qr/.svn/, case_insensitive => 1, sort => 1, path => \"src///*.cpp\", match => qr(^src/(.*?)\\.cpp$), derive => ['src/$1.o','src/$1.hpp']); push @pa...
"* [File::Wildcard::Find](https://metacpan.org/pod/File::Wildcard::Find) – `findbegin($dir); push @paths, $f while $f = findnext()` или  `findbegin($dir); @paths = findall()`.\n"
"* [File::Util](https://metacpan.org/pod/File::Util) – `File::Util->new->list_dir($dir, qw/ --pattern=\\.txt$ --files-only --recurse /)`.\n"
"* [Mojo::File](https://metacpan.org/pod/Mojo::File) – `say for path($path)->list_tree({hidden => 1, dir => 1})->each`.\n"
"* [Path::Find](https://metacpan.org/pod/Path::Find) – `@paths = path_find( $dir, \"*.png\" )`. Для сложных запросов использует _matchable_: `my $sub = matchable( sub { my( $entry, $directory, $fullname, $depth ) = @_; $...
"* [Path::Extended::Dir](https://metacpan.org/pod/Path::Extended::Dir) – `@paths = Path::Extended::Dir->new($dir)->find('*.txt')`.\n"
"* [Path::Iterator::Rule](https://metacpan.org/pod/Path::Iterator::Rule) – `$i = Path::Iterator::Rule->new->file; @paths = $i->clone->size(\">10k\")->all(@dirs); $i->size(\"<10k\")...`.\n"
"* [Path::Class::Each](https://metacpan.org/pod/Path::Class::Each) – `dir($dir)->each(sub { push @paths, \"$_\" })`.\n"
"* [Path::Class::Iterator](https://metacpan.org/pod/Path::Class::Iterator) – `$i = Path::Class::Iterator->new(root => $dir, depth => 2); until ($i->done) { push @paths, $i->next->stringify }`.\n"
"* [Path::Class::Rule](https://metacpan.org/pod/Path::Class::Rule) – `@paths = Path::Class::Rule->new->file->size(\">10k\")->all($dir)`."
msgstr ""
"* [AudioFile::Find](https://metacpan.org/pod/AudioFile::Find) – searches for audio files in the specified directory. Allows you to filter them by attributes: title, artist, genre, album and track.\n"
"* [Directory::Iterator](https://metacpan.org/pod/Directory::Iterator) – `$it = Directory::Iterator->new($dir, %opts); push @paths, $_ while <$it>`.\n"
"* [IO::All](https://metacpan.org/pod/IO::All) – `@paths = map { \"$_\" } grep { -f $_ && $_->size > 10*1024 } io(\".\")->all(0)`.\n"
"* [IO::All::Rule](https://metacpan.org/pod/IO::All::Rule) – `$next = IO::All::Rule->new->file->size(\">10k\")->iter($dir1, $dir2); push @paths, \"$f\" while $f = $next->()`.\n"
"* [File::Find](https://metacpan.org/pod/File::Find) – `find( sub { push @paths, $File::Find::name if /\\.png/ }, $dir )`.\n"
"* [File::Find::utf8](https://metacpan.org/pod/File::Find::utf8) – like [File::Find](https://metacpan.org/pod/File::Find), only file paths are in _utf8_.\n"
"* [File::Find::Age](https://metacpan.org/pod/File::Find::Age) – sorts files by modification time (inherits [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule)): `File::Find::Age->in($dir1, $dir2)`.\n"
"* [File::Find::Declare](https://metacpan.org/pod/File::Find::Declare) – `@paths = File::Find::Declare->new({ size => '>10K', perms => 'wr-wr-wr-', modified => '<2010-01-30', recurse => 1, dirs => [$dir1] })->find`.\n"
"* [File::Find::Iterator](https://metacpan.org/pod/File::Find::Iterator) – has an OOP interface with an iterator and the `imap` and `igrep` functions.\n"
"* [File::Find::Match](https://metacpan.org/pod/File::Find::Match) – calls a handler for each matching filter. Similar to `switch`.\n"
"* [File::Find::Node](https://metacpan.org/pod/File::Find::Node) – traverses the file hierarchy in parallel by several processes: `tie @paths, IPC::Shareable, { key => \"GLUE STRING\", create => 1 }; File::Find::Node->new(\".\")->process(sub { my $...
"* [File::Find::Fast](https://metacpan.org/pod/File::Find::Fast) – `@paths = @{ find($dir) }`.\n"
"* [File::Find::Object](https://metacpan.org/pod/File::Find::Object) – has an OOP interface with an iterator.\n"
"* [File::Find::Parallel](https://metacpan.org/pod/File::Find::Parallel) – can compare two directories and return their union, intersection and quantitative intersection.\n"
"* [File::Find::Random](https://metacpan.org/pod/File::Find::Random) – selects a file or directory at random from the file hierarchy.\n"
"* [File::Find::Rex](https://metacpan.org/pod/File::Find::Rex) – `@paths = File::Find::Rex->new(recursive => 1, ignore_hidden => 1)->query($dir, qr/^b/i)`.\n"
"* [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule) – `@files = File::Find::Rule->any( File::Find::Rule->file->name('*.mp3', '*.ogg')->size('>2M'), File::Find::Rule->empty )->in($dir1, $dir2);`. Has an iterator, procedural interface an...
"* [File::Find::Wanted](https://metacpan.org/pod/File::Find::Wanted) – `@paths = find_wanted( sub { -f && /\\.png/ }, $dir )`.\n"
"* [File::Hotfolder](https://metacpan.org/pod/File::Hotfolder) – `watch( $dir, callback => sub { push @paths, shift } )->loop`. Powered by `AnyEvent`. Customizable. There is parallelization into several processes.\n"
"* [File::Mirror](https://metacpan.org/pod/File::Mirror) – also forms a parallel path for copying files: `recursive { my ($src, $dst) = @_; push @paths, $src } '/path/A', '/path/B'`.\n"
"* [File::Set](https://metacpan.org/pod/File::Set) – `$fs = File::Set->new; $fs->add($dir); @paths = map { $_->[0] } $fs->get_path_list`.\n"
"* [File::Wildcard](https://metacpan.org/pod/File::Wildcard) – `$fw = File::Wildcard->new(exclude => qr/.svn/, case_insensitive => 1, sort => 1, path => \"src///*.cpp\", match => qr(^src/(.*?)\\.cpp$), derive => ['src/$1.o','src/$1.hpp']); push @pa...
"* [File::Wildcard::Find](https://metacpan.org/pod/File::Wildcard::Find) – `findbegin($dir); push @paths, $f while $f = findnext()` or `findbegin($dir); @paths = findall()`.\n"
"* [File::Util](https://metacpan.org/pod/File::Util) – `File::Util->new->list_dir($dir, qw/ --pattern=\\.txt$ --files-only --recurse /)`.\n"
"* [Mojo::File](https://metacpan.org/pod/Mojo::File) – `say for path($path)->list_tree({hidden => 1, dir => 1})->each`.\n"
"* [Path::Find](https://metacpan.org/pod/Path::Find) – `@paths = path_find( $dir, \"*.png\" )`. For complex queries, use _matchable_: `my $sub = matchable( sub { my( $entry, $directory, $fullname, $depth ) = @_; $depth <= 3 }`.\n"
"* [Path::Extended::Dir](https://metacpan.org/pod/Path::Extended::Dir) – `@paths = Path::Extended::Dir->new($dir)->find('*.txt')`.\n"
"* [Path::Iterator::Rule](https://metacpan.org/pod/Path::Iterator::Rule) – `$i = Path::Iterator::Rule->new->file; @paths = $i->clone->size(\">10k\")->all(@dirs); $i->size(\"<10k\")...`.\n"
"* [Path::Class::Each](https://metacpan.org/pod/Path::Class::Each) – `dir($dir)->each(sub { push @paths, \"$_\" })`.\n"
"* [Path::Class::Iterator](https://metacpan.org/pod/Path::Class::Iterator) – `$i = Path::Class::Iterator->new(root => $dir, depth => 2); until ($i->done) { push @paths, $i->next->stringify }`.\n"
"* [Path::Class::Rule](https://metacpan.org/pod/Path::Class::Rule) – `@paths = Path::Class::Rule->new->file->size(\">10k\")->all($dir)`."

lib/Aion/Fs.md  view on Meta::CPAN

```perl
use Aion::Fs;

lay mkpath "hello/world.txt", "hi!";
lay mkpath "hello/moon.txt", "noreplace";
lay mkpath "hello/big/world.txt", "hellow!";
lay mkpath "hello/small/world.txt", "noenter";

mtime "hello";  # ~> ^\d+(\.\d+)?$

[map cat, grep -f, find ["hello/big", "hello/small"]];  # --> [qw/ hellow! noenter /]

my @noreplaced = replace { s/h/$a $b H/ }
    find "hello", "-f", "*.txt", qr/\.txt$/, sub { /\.txt$/ },
        noenter "*small*",
            errorenter { warn "find $_: $!" };

\@noreplaced; # --> ["hello/moon.txt"]

cat "hello/world.txt";       # => hello/world.txt :utf8 Hi!
cat "hello/moon.txt";        # => noreplace

lib/Aion/Fs.md  view on Meta::CPAN


my $count = 0;
find "ex", sub { find_stop if ++$count == 3; 1};
$count # -> 3
```

### See also

* [AudioFile::Find](https://metacpan.org/pod/AudioFile::Find) – ищет аудиофайлы в указанной директории. Позволяет фильтровать их по атрибутам: названию, артисту, жа...
* [Directory::Iterator](https://metacpan.org/pod/Directory::Iterator) – `$it = Directory::Iterator->new($dir, %opts); push @paths, $_ while <$it>`.
* [IO::All](https://metacpan.org/pod/IO::All) – `@paths = map { "$_" } grep { -f $_ && $_->size > 10*1024 } io(".")->all(0)`.
* [IO::All::Rule](https://metacpan.org/pod/IO::All::Rule) – `$next = IO::All::Rule->new->file->size(">10k")->iter($dir1, $dir2); push @paths, "$f" while $f = $next->()`.
* [File::Find](https://metacpan.org/pod/File::Find) – `find( sub { push @paths, $File::Find::name if /\.png/ }, $dir )`.
* [File::Find::utf8](https://metacpan.org/pod/File::Find::utf8) – как [File::Find](https://metacpan.org/pod/File::Find), только пути файлов в _utf8_.
* [File::Find::Age](https://metacpan.org/pod/File::Find::Age) – сортирует файлы по времени модификации (наследует [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule)): `File::Find::Age->in($dir1,...
* [File::Find::Declare](https://metacpan.org/pod/File::Find::Declare) – `@paths = File::Find::Declare->new({ size => '>10K', perms => 'wr-wr-wr-', modified => '<2010-01-30', recurse => 1, dirs => [$dir1] })->find`.
* [File::Find::Iterator](https://metacpan.org/pod/File::Find::Iterator) – имеет ООП интерфейс с итератором и функции `imap` и `igrep`.
* [File::Find::Match](https://metacpan.org/pod/File::Find::Match) – вызывает обработчик на каждый подошедший фильтр. Похож на `switch`.
* [File::Find::Node](https://metacpan.org/pod/File::Find::Node) – обходит иерархию файлов параллельно несколькими процессами: `tie @paths, IPC::Shareable, { key => "GLUE STRING", create => 1 }; F...
* [File::Find::Fast](https://metacpan.org/pod/File::Find::Fast) – `@paths = @{ find($dir) }`.
* [File::Find::Object](https://metacpan.org/pod/File::Find::Object) – имеет ООП интерфейс с итератором.
* [File::Find::Parallel](https://metacpan.org/pod/File::Find::Parallel) – умеет сравнивать два каталога и возвращать их объединение, пересечение и количественное перес...
* [File::Find::Random](https://metacpan.org/pod/File::Find::Random) – выбирает файл или директорию наугад из иерархии файлов.
* [File::Find::Rex](https://metacpan.org/pod/File::Find::Rex) – `@paths = File::Find::Rex->new(recursive => 1, ignore_hidden => 1)->query($dir, qr/^b/i)`.
* [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule) – `@files = File::Find::Rule->any( File::Find::Rule->file->name('*.mp3', '*.ogg')->size('>2M'), File::Find::Rule->empty )->in($dir1, $dir2);`. Имеет итератор, процед...
* [File::Find::Wanted](https://metacpan.org/pod/File::Find::Wanted) – `@paths = find_wanted( sub { -f && /\.png/ }, $dir )`.
* [File::Hotfolder](https://metacpan.org/pod/File::Hotfolder) – `watch( $dir, callback => sub { push @paths, shift } )->loop`. Работает на `AnyEvent`. Настраиваемый. Есть распараллеливание на неско...
* [File::Mirror](https://metacpan.org/pod/File::Mirror) – формирует так же параллельный путь для копирования файлов: `recursive { my ($src, $dst) = @_; push @paths, $src } '/path/A', '/path/B'`.
* [File::Set](https://metacpan.org/pod/File::Set) – `$fs = File::Set->new; $fs->add($dir); @paths = map { $_->[0] } $fs->get_path_list`.
* [File::Wildcard](https://metacpan.org/pod/File::Wildcard) – `$fw = File::Wildcard->new(exclude => qr/.svn/, case_insensitive => 1, sort => 1, path => "src///*.cpp", match => qr(^src/(.*?)\.cpp$), derive => ['src/$1.o','src/$1.hpp']); push @paths,...
* [File::Wildcard::Find](https://metacpan.org/pod/File::Wildcard::Find) – `findbegin($dir); push @paths, $f while $f = findnext()` или  `findbegin($dir); @paths = findall()`.
* [File::Util](https://metacpan.org/pod/File::Util) – `File::Util->new->list_dir($dir, qw/ --pattern=\.txt$ --files-only --recurse /)`.
* [Mojo::File](https://metacpan.org/pod/Mojo::File) – `say for path($path)->list_tree({hidden => 1, dir => 1})->each`.
* [Path::Find](https://metacpan.org/pod/Path::Find) – `@paths = path_find( $dir, "*.png" )`. Для сложных запросов использует _matchable_: `my $sub = matchable( sub { my( $entry, $directory, $fullname, $depth ) = @_; $dep...
* [Path::Extended::Dir](https://metacpan.org/pod/Path::Extended::Dir) – `@paths = Path::Extended::Dir->new($dir)->find('*.txt')`.
* [Path::Iterator::Rule](https://metacpan.org/pod/Path::Iterator::Rule) – `$i = Path::Iterator::Rule->new->file; @paths = $i->clone->size(">10k")->all(@dirs); $i->size("<10k")...`.
* [Path::Class::Each](https://metacpan.org/pod/Path::Class::Each) – `dir($dir)->each(sub { push @paths, "$_" })`.
* [Path::Class::Iterator](https://metacpan.org/pod/Path::Class::Iterator) – `$i = Path::Class::Iterator->new(root => $dir, depth => 2); until ($i->done) { push @paths, $i->next->stringify }`.
* [Path::Class::Rule](https://metacpan.org/pod/Path::Class::Rule) – `@paths = Path::Class::Rule->new->file->size(">10k")->all($dir)`.

lib/Aion/Fs.md  view on Meta::CPAN

Файл lib/N.pm:
```perl
package N;
sub ex { 123 }
1;
```

```perl
use lib "lib";
include("A")->new               # ~> A=HASH\(0x\w+\)
[map include, qw/A N/]          # --> [qw/A N/]
{ local $_="N"; include->ex }   # -> 123
```

## catonce (;$file)

Считывает файл в первый раз. Любая последующая попытка считать этот файл возвращает `undef`. Используется для вставки модулей js и css в резулÑ...

* `$file` может содержать массивы из двух элементов. Первый рассматривается как путь, а второй – как слой. Слой по умолчанию – `:utf8`.
* Если `$file` не указан – использует `$_`.

lib/Aion/Fs.md  view on Meta::CPAN


eval { goto_editor "`", 1 }; $@  # ~> `:1 --> 512
```

## from_pkg (;$pkg)

Переводит пакет в путь ФС. Без параметра использует `$_`.

```perl
from_pkg "Aion::Fs"  # => Aion/Fs.pm
[map from_pkg, "Aion::Fs", "A::B::C"]  # --> ["Aion/Fs.pm", "A/B/C.pm"]
```

## to_pkg (;$path)

Переводит путь из ФС в пакет. Без параметра использует `$_`.

```perl
to_pkg "Aion/Fs.pm"  # => Aion::Fs
[map to_pkg, "Aion/Fs.md", "A/B/C.md"]  # --> ["Aion::Fs", "A::B::C"]
```

## from_inc (;$pkg)

Переводит пакет в путь ФС в `@INC`. Файл с пакетом должен существовать в одном из путей `@INC`. Без параметра использует `$_`.

```perl
from_inc "Aion::Fs" # -> $INC{'Aion/Fs.pm'}
[map from_inc, "A::B::C", "Aion::Fs"]  # --> [$INC{'Aion/Fs.pm'}]

from_inc "A::B::C" # -> undef
```

## to_inc (;$path)

Переводит путь из ФС в `@INC` в пакет. Без параметра использует `$_`.

```perl
to_inc $INC{'Aion/Fs.pm'} # => Aion::Fs
[map to_inc,"A/B/C.pm", $INC{'Aion/Fs.pm'}]  # --> ["Aion::Fs"]

to_inc 'Aion/Fs.pm' # -> undef
```

## ilay (;$path)

Создаёт файловый дескриптор. Он умеет закрываться, как только на него исчезнет последняя ссылка.

Так же имеет метод `path`, к-й возвращает путь к файлу.

lib/Aion/Fs.pm  view on Meta::CPAN

	delete @res{keys %{$fs->{remove}->{$_}}} for @remove;
	
	return %res, %$_;
}

sub _join(@) {
	my ($match, @format) = @_;
	my $fs = _fs;
	my $trans = $fs->{before_split} // sub {$_[0]};
	my %f = _match $match, $fs;
	join "", List::Util::pairmap {
		my @keys = ref $a? @$a: $a;
		my $is = List::Util::first {defined $f{$_}} @keys;
		defined $is? do {
			my ($if, $format) = ref $b? @$b: (undef, $b);
			
			my @val = map $trans->($f{$_}), @keys;
			defined $if && $val[0] eq $if? $if:
				$format !~ /%s/? $format:
					sprintf($format, @val)
		}: () 
	} @format
}

# Синтаксисы файловых путей в разных ОС
my %FS;
my @FS = (

lib/Aion/Fs.pm  view on Meta::CPAN

		\z!xsn,
		join => sub {
			_join [qw/path/],
				[qw/userid file ext volume/] => "%s %s %s %s",
		},
	},
	
);

# Инициализация по имени
%FS = map {
	$_->{symdirquote} = quotemeta $_->{symdir};
	$_->{symextquote} = quotemeta $_->{symext};
	
	my @S;
	while($_->{regexp} =~ m{
		\\ .
		| (?<open> \( ( \?<(?<group> \w+ )> )? )
		| (?<close> \) )
	}gx) {
		if($+{open}) {

lib/Aion/Fs.pm  view on Meta::CPAN

			
			$group //= $g2;
			$_->{group}{$group} = do {
				my $x = substr $_->{regexp}, $pos, length($`) - $pos;
				qr/()^$x\z/xsn
			} if defined $group;
		}
	}
	
	my $x = $_;
	ref $_->{name}? (map { ($_ => $x) } @{$_->{name}}): ($_->{name} => $_)
} @FS;

sub _fs() { $FS{lc $^O} // $FS{unix} }

# Мы находимся в ОС семейства UNIX
sub isUNIX() { _fs->{name} eq "unix" }

# Разбивает директорию на составляющие
sub splitdir(;$) {
	my ($dir) = @_ == 0? $_: @_;

lib/Aion/Fs.pm  view on Meta::CPAN

	if(ref $path eq "HASH") {
		local $_ = $path;
		return $fs->{join}->();
	}
	
	($path) = @$path if ref $path;
	
	$path = $fs->{before_split}->($path) if exists $fs->{before_split};
	
	+{
		$path =~ $fs->{regexp}? (map { $_ ne "ext" && $+{$_} eq ""? (): ($_ => $+{$_}) } keys %+): (error => 1),
		path => $path,
	}
}

# Переводит путь из формата одной ОС в другую
sub transpath ($$;$) {
	my ($path, $from, $to) = @_ == 2? ($_, @_): @_;
	my (@dir, @folder, @ext);
	{ local $^O = $from;
		$path = path $path;

lib/Aion/Fs.pm  view on Meta::CPAN

# 		group_can_exec group_can_read group_can_write
# 		other_can_exec other_can_read other_can_write
# 	/} = (
# 		
# 	);
	\%sta
}

# Файловые фильтры
sub _filters(@) {
	map {
		if(ref $_ eq "CODE") {$_}
		elsif(ref $_ eq "Regexp") { my $re = $_; sub { $_ =~ $re } }
		elsif(/^-([a-z]+)$/) {
			eval join "", "sub { ", (join " && ", map "-$_()", split //, $1), " }"
		}
		else { my $re = wildcard(); sub { $_ =~ $re } }
	} @_
}

# Найти файлы
sub find(;@) {
	my $files = @_? shift: $_;
    $files = [$files] unless ref $files;

lib/Aion/Fs.pm  view on Meta::CPAN

		return $path if -f $path;
	}

	return;
}

# Из файлового пути в @INC в пакет
sub to_inc(;$) {
	my ($path) = @_ == 0? $_: @_;
	
	my $inc = join "|", map quotemeta, @INC;
	
	return to_pkg $' if $path =~ m!^(?:$inc)/!;

	return;
}

# Подключает модуль, если он ещё не подключён, и возвращает его
sub include(;$) {
	my ($pkg) = @_ == 0? $_: @_;
	return $pkg if $pkg->can("new") || $pkg->can("has");

lib/Aion/Fs.pm  view on Meta::CPAN


	use Aion::Fs;
	
	lay mkpath "hello/world.txt", "hi!";
	lay mkpath "hello/moon.txt", "noreplace";
	lay mkpath "hello/big/world.txt", "hellow!";
	lay mkpath "hello/small/world.txt", "noenter";
	
	mtime "hello";  # ~> ^\d+(\.\d+)?$
	
	[map cat, grep -f, find ["hello/big", "hello/small"]];  # --> [qw/ hellow! noenter /]
	
	my @noreplaced = replace { s/h/$a $b H/ }
	    find "hello", "-f", "*.txt", qr/\.txt$/, sub { /\.txt$/ },
	        noenter "*small*",
	            errorenter { warn "find $_: $!" };
	
	\@noreplaced; # --> ["hello/moon.txt"]
	
	cat "hello/world.txt";       # => hello/world.txt :utf8 Hi!
	cat "hello/moon.txt";        # => noreplace

lib/Aion/Fs.pm  view on Meta::CPAN

	$count # -> 3

=head3 See also

=over

=item * L<AudioFile::Find> – searches for audio files in the specified directory. Allows you to filter them by attributes: title, artist, genre, album and track.

=item * L<Directory::Iterator> – C<< $it = Directory::Iterator-E<gt>new($dir, %opts); push @paths, $_ while E<lt>$itE<gt> >>.

=item * L<IO::All> – C<< @paths = map { "$_" } grep { -f $_ && $_-E<gt>size E<gt> 10*1024 } io(".")-E<gt>all(0) >>.

=item * L<IO::All::Rule> – C<< $next = IO::All::Rule-E<gt>new-E<gt>file-E<gt>size("E<gt>10k")-E<gt>iter($dir1, $dir2); push @paths, "$f" while $f = $next-E<gt>() >>.

=item * L<File::Find> – C<find( sub { push @paths, $File::Find::name if /\.png/ }, $dir )>.

=item * L<File::Find::utf8> – like L<File::Find>, only file paths are in I<utf8>.

=item * L<File::Find::Age> – sorts files by modification time (inherits L<File::Find::Rule>): C<< File::Find::Age-E<gt>in($dir1, $dir2) >>.

=item * L<File::Find::Declare> – C<< @paths = File::Find::Declare-E<gt>new({ size =E<gt> 'E<gt>10K', perms =E<gt> 'wr-wr-wr-', modified =E<gt> 'E<lt>2010-01-30', recurse =E<gt> 1, dirs =E<gt> [$dir1] })-E<gt>find >>.

=item * L<File::Find::Iterator> – has an OOP interface with an iterator and the C<imap> and C<igrep> functions.

=item * L<File::Find::Match> – calls a handler for each matching filter. Similar to C<switch>.

=item * L<File::Find::Node> – traverses the file hierarchy in parallel by several processes: C<< tie @paths, IPC::Shareable, { key =E<gt> "GLUE STRING", create =E<gt> 1 }; File::Find::Node-E<gt>new(".")-E<gt>process(sub { my $f = shift; $f-E<gt>for...

=item * L<File::Find::Fast> – C<@paths = @{ find($dir) }>.

=item * L<File::Find::Object> – has an OOP interface with an iterator.

=item * L<File::Find::Parallel> – can compare two directories and return their union, intersection and quantitative intersection.

lib/Aion/Fs.pm  view on Meta::CPAN

=item * L<File::Find::Rex> – C<< @paths = File::Find::Rex-E<gt>new(recursive =E<gt> 1, ignore_hidden =E<gt> 1)-E<gt>query($dir, qr/^b/i) >>.

=item * L<File::Find::Rule> – C<< @files = File::Find::Rule-E<gt>any( File::Find::Rule-E<gt>file-E<gt>name('*.mp3', '*.ogg')-E<gt>size('E<gt>2M'), File::Find::Rule-E<gt>empty )-E<gt>in($dir1, $dir2); >>. Has an iterator, procedural interface and ex...

=item * L<File::Find::Wanted> – C<@paths = find_wanted( sub { -f && /\.png/ }, $dir )>.

=item * L<File::Hotfolder> – C<< watch( $dir, callback =E<gt> sub { push @paths, shift } )-E<gt>loop >>. Powered by C<AnyEvent>. Customizable. There is parallelization into several processes.

=item * L<File::Mirror> – also forms a parallel path for copying files: C<recursive { my ($src, $dst) = @_; push @paths, $src } '/path/A', '/path/B'>.

=item * L<File::Set> – C<< $fs = File::Set-E<gt>new; $fs-E<gt>add($dir); @paths = map { $_-E<gt>[0] } $fs-E<gt>get_path_list >>.

=item * L<File::Wildcard> – C<< $fw = File::Wildcard-E<gt>new(exclude =E<gt> qr/.svn/, case_insensitive =E<gt> 1, sort =E<gt> 1, path =E<gt> "src///*.cpp", match =E<gt> qr(^src/(.*?)\.cpp$), derive =E<gt> ['src/$1.o','src/$1.hpp']); push @paths, $f...

=item * L<File::Wildcard::Find> – C<findbegin($dir); push @paths, $f while $f = findnext()> or C<findbegin($dir); @paths = findall()>.

=item * L<File::Util> – C<< File::Util-E<gt>new-E<gt>list_dir($dir, qw/ --pattern=\.txt$ --files-only --recurse /) >>.

=item * L<Mojo::File> – C<< say for path($path)-E<gt>list_tree({hidden =E<gt> 1, dir =E<gt> 1})-E<gt>each >>.

=item * L<Path::Find> – C<@paths = path_find( $dir, "*.png" )>. For complex queries, use I<matchable>: C<< my $sub = matchable( sub { my( $entry, $directory, $fullname, $depth ) = @_; $depth E<lt>= 3 } >>.

lib/Aion/Fs.pm  view on Meta::CPAN

lib/N.pm file:

	package N;
	sub ex { 123 }
	1;



	use lib "lib";
	include("A")->new               # ~> A=HASH\(0x\w+\)
	[map include, qw/A N/]          # --> [qw/A N/]
	{ local $_="N"; include->ex }   # -> 123

=head2 catonce (;$file)

Reads the file for the first time. Any subsequent attempt to read this file returns C<undef>. Used to insert js and css modules into the resulting file. Without a parameter, uses C<$_>.

=over

=item * C<$file> can contain arrays of two elements. The first is considered as a path, and the second as a layer. The default layer is C<:utf8>.

lib/Aion/Fs.pm  view on Meta::CPAN

	goto_editor "mypath", 10;
	cat "ed.txt"  # => mypath:10\n
	
	eval { goto_editor "`", 1 }; $@  # ~> `:1 --> 512

=head2 from_pkg (;$pkg)

Transfers the packet to the FS path. Without a parameter, uses C<$_>.

	from_pkg "Aion::Fs"  # => Aion/Fs.pm
	[map from_pkg, "Aion::Fs", "A::B::C"]  # --> ["Aion/Fs.pm", "A/B/C.pm"]

=head2 to_pkg (;$path)

Translates the path from the FS to the package. Without a parameter, uses C<$_>.

	to_pkg "Aion/Fs.pm"  # => Aion::Fs
	[map to_pkg, "Aion/Fs.md", "A/B/C.md"]  # --> ["Aion::Fs", "A::B::C"]

=head2 from_inc (;$pkg)

Translates the packet to the FS path in C<@INC>. The package file must exist in one of the C<@INC> paths. Without a parameter, uses C<$_>.

	from_inc "Aion::Fs" # -> $INC{'Aion/Fs.pm'}
	[map from_inc, "A::B::C", "Aion::Fs"]  # --> [$INC{'Aion/Fs.pm'}]
	
	from_inc "A::B::C" # -> undef

=head2 to_inc (;$path)

Translates the path from FS to C<@INC> into a package. Without a parameter, uses C<$_>.

	to_inc $INC{'Aion/Fs.pm'} # => Aion::Fs
	[map to_inc,"A/B/C.pm", $INC{'Aion/Fs.pm'}]  # --> ["Aion::Fs"]
	
	to_inc 'Aion/Fs.pm' # -> undef

=head2 ilay (;$path)

Creates a file descriptor. It knows how to close as soon as the last link to it disappears.

It also has a C<path> method, which returns the path to the file.

	my $test_file = "test_ilay_complete.txt";

t/aion/fs.t  view on Meta::CPAN

subtest 'SYNOPSIS' => sub { 
use Aion::Fs;

lay mkpath "hello/world.txt", "hi!";
lay mkpath "hello/moon.txt", "noreplace";
lay mkpath "hello/big/world.txt", "hellow!";
lay mkpath "hello/small/world.txt", "noenter";

::like scalar do {mtime "hello";}, qr{^\d+(\.\d+)?$}, 'mtime "hello";  # ~> ^\d+(\.\d+)?$'; undef $::_g0; undef $::_e0;

local ($::_g0 = do {[map cat, grep -f, find ["hello/big", "hello/small"]];}, $::_e0 = do {[qw/ hellow! noenter /]}); ::is_deeply $::_g0, $::_e0, '[map cat, grep -f, find ["hello/big", "hello/small"]];  # --> [qw/ hellow! noenter /]' or ::diag ::_stru...

my @noreplaced = replace { s/h/$a $b H/ }
    find "hello", "-f", "*.txt", qr/\.txt$/, sub { /\.txt$/ },
        noenter "*small*",
            errorenter { warn "find $_: $!" };

local ($::_g0 = do {\@noreplaced;}, $::_e0 = do {["hello/moon.txt"]}); ::is_deeply $::_g0, $::_e0, '\@noreplaced; # --> ["hello/moon.txt"]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {cat "hello/world.txt";}, $::_e0 = "hello/world.txt :utf8 Hi!"); ::ok $::_g0 eq $::_e0, 'cat "hello/world.txt";       # => hello/world.txt :utf8 Hi!' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {cat "hello/moon.txt";}, $::_e0 = "noreplace"); ::ok $::_g0 eq $::_e0, 'cat "hello/moon.txt";        # => noreplace' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

t/aion/fs.t  view on Meta::CPAN


my $count = 0;
find "ex", sub { find_stop if ++$count == 3; 1};
local ($::_g0 = do {$count}, $::_e0 = do {3}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$count # -> 3' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ### See also
# 
# * [AudioFile::Find](https://metacpan.org/pod/AudioFile::Find) – ищет аудиофайлы в указанной директории. Позволяет фильтровать их по атрибутам: названию, артисту, ж...
# * [Directory::Iterator](https://metacpan.org/pod/Directory::Iterator) – `$it = Directory::Iterator->new($dir, %opts); push @paths, $_ while <$it>`.
# * [IO::All](https://metacpan.org/pod/IO::All) – `@paths = map { "$_" } grep { -f $_ && $_->size > 10*1024 } io(".")->all(0)`.
# * [IO::All::Rule](https://metacpan.org/pod/IO::All::Rule) – `$next = IO::All::Rule->new->file->size(">10k")->iter($dir1, $dir2); push @paths, "$f" while $f = $next->()`.
# * [File::Find](https://metacpan.org/pod/File::Find) – `find( sub { push @paths, $File::Find::name if /\.png/ }, $dir )`.
# * [File::Find::utf8](https://metacpan.org/pod/File::Find::utf8) – как [File::Find](https://metacpan.org/pod/File::Find), только пути файлов в _utf8_.
# * [File::Find::Age](https://metacpan.org/pod/File::Find::Age) – сортирует файлы по времени модификации (наследует [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule)): `File::Find::Age->in($dir...
# * [File::Find::Declare](https://metacpan.org/pod/File::Find::Declare) – `@paths = File::Find::Declare->new({ size => '>10K', perms => 'wr-wr-wr-', modified => '<2010-01-30', recurse => 1, dirs => [$dir1] })->find`.
# * [File::Find::Iterator](https://metacpan.org/pod/File::Find::Iterator) – имеет ООП интерфейс с итератором и функции `imap` и `igrep`.
# * [File::Find::Match](https://metacpan.org/pod/File::Find::Match) – вызывает обработчик на каждый подошедший фильтр. Похож на `switch`.
# * [File::Find::Node](https://metacpan.org/pod/File::Find::Node) – обходит иерархию файлов параллельно несколькими процессами: `tie @paths, IPC::Shareable, { key => "GLUE STRING", create => 1 };...
# * [File::Find::Fast](https://metacpan.org/pod/File::Find::Fast) – `@paths = @{ find($dir) }`.
# * [File::Find::Object](https://metacpan.org/pod/File::Find::Object) – имеет ООП интерфейс с итератором.
# * [File::Find::Parallel](https://metacpan.org/pod/File::Find::Parallel) – умеет сравнивать два каталога и возвращать их объединение, пересечение и количественное пере...
# * [File::Find::Random](https://metacpan.org/pod/File::Find::Random) – выбирает файл или директорию наугад из иерархии файлов.
# * [File::Find::Rex](https://metacpan.org/pod/File::Find::Rex) – `@paths = File::Find::Rex->new(recursive => 1, ignore_hidden => 1)->query($dir, qr/^b/i)`.
# * [File::Find::Rule](https://metacpan.org/pod/File::Find::Rule) – `@files = File::Find::Rule->any( File::Find::Rule->file->name('*.mp3', '*.ogg')->size('>2M'), File::Find::Rule->empty )->in($dir1, $dir2);`. Имеет итератор, проце...
# * [File::Find::Wanted](https://metacpan.org/pod/File::Find::Wanted) – `@paths = find_wanted( sub { -f && /\.png/ }, $dir )`.
# * [File::Hotfolder](https://metacpan.org/pod/File::Hotfolder) – `watch( $dir, callback => sub { push @paths, shift } )->loop`. Работает на `AnyEvent`. Настраиваемый. Есть распараллеливание на неск...
# * [File::Mirror](https://metacpan.org/pod/File::Mirror) – формирует так же параллельный путь для копирования файлов: `recursive { my ($src, $dst) = @_; push @paths, $src } '/path/A', '/path/B'`.
# * [File::Set](https://metacpan.org/pod/File::Set) – `$fs = File::Set->new; $fs->add($dir); @paths = map { $_->[0] } $fs->get_path_list`.
# * [File::Wildcard](https://metacpan.org/pod/File::Wildcard) – `$fw = File::Wildcard->new(exclude => qr/.svn/, case_insensitive => 1, sort => 1, path => "src///*.cpp", match => qr(^src/(.*?)\.cpp$), derive => ['src/$1.o','src/$1.hpp']); push @path...
# * [File::Wildcard::Find](https://metacpan.org/pod/File::Wildcard::Find) – `findbegin($dir); push @paths, $f while $f = findnext()` или  `findbegin($dir); @paths = findall()`.
# * [File::Util](https://metacpan.org/pod/File::Util) – `File::Util->new->list_dir($dir, qw/ --pattern=\.txt$ --files-only --recurse /)`.
# * [Mojo::File](https://metacpan.org/pod/Mojo::File) – `say for path($path)->list_tree({hidden => 1, dir => 1})->each`.
# * [Path::Find](https://metacpan.org/pod/Path::Find) – `@paths = path_find( $dir, "*.png" )`. Для сложных запросов использует _matchable_: `my $sub = matchable( sub { my( $entry, $directory, $fullname, $depth ) = @_; $d...
# * [Path::Extended::Dir](https://metacpan.org/pod/Path::Extended::Dir) – `@paths = Path::Extended::Dir->new($dir)->find('*.txt')`.
# * [Path::Iterator::Rule](https://metacpan.org/pod/Path::Iterator::Rule) – `$i = Path::Iterator::Rule->new->file; @paths = $i->clone->size(">10k")->all(@dirs); $i->size("<10k")...`.
# * [Path::Class::Each](https://metacpan.org/pod/Path::Class::Each) – `dir($dir)->each(sub { push @paths, "$_" })`.
# * [Path::Class::Iterator](https://metacpan.org/pod/Path::Class::Iterator) – `$i = Path::Class::Iterator->new(root => $dir, depth => 2); until ($i->done) { push @paths, $i->next->stringify }`.
# * [Path::Class::Rule](https://metacpan.org/pod/Path::Class::Rule) – `@paths = Path::Class::Rule->new->file->size(">10k")->all($dir)`.

t/aion/fs.t  view on Meta::CPAN

# Файл lib/N.pm:
#@> lib/N.pm
#>> package N;
#>> sub ex { 123 }
#>> 1;
#@< EOF
# 
::done_testing; }; subtest 'include (;$pkg)' => sub { 
use lib "lib";
::like scalar do {include("A")->new}, qr{A=HASH\(0x\w+\)}, 'include("A")->new               # ~> A=HASH\(0x\w+\)'; undef $::_g0; undef $::_e0;
local ($::_g0 = do {[map include, qw/A N/]}, $::_e0 = do {[qw/A N/]}); ::is_deeply $::_g0, $::_e0, '[map include, qw/A N/]          # --> [qw/A N/]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {{ local $_="N"; include->ex }}, $::_e0 = do {123}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{ local $_="N"; include->ex }   # -> 123' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## catonce (;$file)
# 
# Считывает файл в первый раз. Любая последующая попытка считать этот файл возвращает `undef`. Используется для вставки модулей js и css в резуÐ...
# 
# * `$file` может содержать массивы из двух элементов. Первый рассматривается как путь, а второй – как слой. Слой по умолчанию – `:utf8`.
# * Если `$file` не указан – использует `$_`.
# 

t/aion/fs.t  view on Meta::CPAN


::like scalar do {eval { goto_editor "`", 1 }; $@}, qr{`:1 --> 512}, 'eval { goto_editor "`", 1 }; $@  # ~> `:1 --> 512'; undef $::_g0; undef $::_e0;

# 
# ## from_pkg (;$pkg)
# 
# Переводит пакет в путь ФС. Без параметра использует `$_`.
# 
::done_testing; }; subtest 'from_pkg (;$pkg)' => sub { 
local ($::_g0 = do {from_pkg "Aion::Fs"}, $::_e0 = "Aion/Fs.pm"); ::ok $::_g0 eq $::_e0, 'from_pkg "Aion::Fs"  # => Aion/Fs.pm' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {[map from_pkg, "Aion::Fs", "A::B::C"]}, $::_e0 = do {["Aion/Fs.pm", "A/B/C.pm"]}); ::is_deeply $::_g0, $::_e0, '[map from_pkg, "Aion::Fs", "A::B::C"]  # --> ["Aion/Fs.pm", "A/B/C.pm"]' or ::diag ::_struct_diff($::_g0, $::_e0); und...

# 
# ## to_pkg (;$path)
# 
# Переводит путь из ФС в пакет. Без параметра использует `$_`.
# 
::done_testing; }; subtest 'to_pkg (;$path)' => sub { 
local ($::_g0 = do {to_pkg "Aion/Fs.pm"}, $::_e0 = "Aion::Fs"); ::ok $::_g0 eq $::_e0, 'to_pkg "Aion/Fs.pm"  # => Aion::Fs' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {[map to_pkg, "Aion/Fs.md", "A/B/C.md"]}, $::_e0 = do {["Aion::Fs", "A::B::C"]}); ::is_deeply $::_g0, $::_e0, '[map to_pkg, "Aion/Fs.md", "A/B/C.md"]  # --> ["Aion::Fs", "A::B::C"]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $...

# 
# ## from_inc (;$pkg)
# 
# Переводит пакет в путь ФС в `@INC`. Файл с пакетом должен существовать в одном из путей `@INC`. Без параметра использует `$_`.
# 
::done_testing; }; subtest 'from_inc (;$pkg)' => sub { 
local ($::_g0 = do {from_inc "Aion::Fs"}, $::_e0 = do {$INC{'Aion/Fs.pm'}}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'from_inc "Aion::Fs" # -> $INC{\'Aion/Fs.pm\'}' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $:...
local ($::_g0 = do {[map from_inc, "A::B::C", "Aion::Fs"]}, $::_e0 = do {[$INC{'Aion/Fs.pm'}]}); ::is_deeply $::_g0, $::_e0, '[map from_inc, "A::B::C", "Aion::Fs"]  # --> [$INC{\'Aion/Fs.pm\'}]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0;...

local ($::_g0 = do {from_inc "A::B::C"}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'from_inc "A::B::C" # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## to_inc (;$path)
# 
# Переводит путь из ФС в `@INC` в пакет. Без параметра использует `$_`.
# 
::done_testing; }; subtest 'to_inc (;$path)' => sub { 
local ($::_g0 = do {to_inc $INC{'Aion/Fs.pm'}}, $::_e0 = "Aion::Fs"); ::ok $::_g0 eq $::_e0, 'to_inc $INC{\'Aion/Fs.pm\'} # => Aion::Fs' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {[map to_inc,"A/B/C.pm", $INC{'Aion/Fs.pm'}]}, $::_e0 = do {["Aion::Fs"]}); ::is_deeply $::_g0, $::_e0, '[map to_inc,"A/B/C.pm", $INC{\'Aion/Fs.pm\'}]  # --> ["Aion::Fs"]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; und...

local ($::_g0 = do {to_inc 'Aion/Fs.pm'}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'to_inc \'Aion/Fs.pm\' # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## ilay (;$path)
# 
# Создаёт файловый дескриптор. Он умеет закрываться, как только на него исчезнет последняя ссылка.
# 
# Так же имеет метод `path`, к-й возвращает путь к файлу.
# 



( run in 1.893 second using v1.01-cache-2.11-cpan-0d23b851a93 )