Aion-Fs

 view release on metacpan or  search on metacpan

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

# 
# * `unlink` + `rmdir`.
# * [File::Path](https://metacpan.org/pod/File::Path) – `remove_tree("dir")`.
# * [File::Path::Tiny](https://metacpan.org/pod/File::Path::Tiny) – `File::Path::Tiny::rm($path)`. Не выбрасывает исключений.
# * [Mojo::File](https://metacpan.org/pod/Mojo::File) – `path($file)->remove`.
# 
# ## replace (&sub, @files)
# 
# Заменяет каждый файл на `$_`, если его изменяет `&sub`. Возвращает файлы, в которых не было замен.
# 
# `@files` может содержать массивы из двух элементов. Первый рассматривается как путь, а второй – как слой. Слой по умолчанию – `:utf8`.
# 
# `&sub` вызывается для каждого файла из `@files`. В неё передаются:
# 
# * `$_` – содержимое файла.
# * `$a` – путь к файлу.
# * `$b` – слой которым был считан файл и которым он будет записан.
# 
# В примере ниже файл "replace.ex" считывается слоем `:utf8`, а записывается слоем `:raw` в функции `replace`:
# 
::done_testing; }; subtest 'replace (&sub, @files)' => sub { 
local $_ = "replace.ex";
lay "abc";
replace { $b = ":utf8"; y/a/¡/ } [$_, ":raw"];
local ($::_g0 = do {cat}, $::_e0 = "¡bc"); ::ok $::_g0 eq $::_e0, 'cat  # => ¡bc' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ### See also
# 
# * [File::Edit](https://metacpan.org/pod/File::Edit) – `File::Edit->new($file)->replace('x', 'y')->save`.
# * [File::Edit::Portable](https://metacpan.org/pod/File::Edit::Portable) – `File::Edit::Portable->new->splice(file => $file, line => 10, contens => ["line1", "line2"])`.
# * [File::Replace](https://metacpan.org/pod/File::Replace) – `($infh,$outfh,$repl) = replace3($file); while (<$infh>) { print $outfh "X: $_" } $repl->finish`.
# * [File::Replace::Inplace](https://metacpan.org/pod/File::Replace::Inplace).
# 
# ## mkpath (;$path)
# 
# Как **mkdir -p**, но считает последнюю часть пути (после последней косой черты) именем файла и не создаёт её каталогом. Без параметра использу...
# 
# * Если `$path` не указан, использует `$_`.
# * Если `$path` является ссылкой на массив, тогда используется путь в качестве первого элемента и права в качестве второго элемента.
# * Права по умолчанию – `0755`.
# * Возвращает `$path`.
# 
::done_testing; }; subtest 'mkpath (;$path)' => sub { 
local $_ = ["A", 0755];
local ($::_g0 = do {mkpath}, $::_e0 = "A"); ::ok $::_g0 eq $::_e0, 'mkpath   # => A' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

::like scalar do {eval { mkpath "/A/" }; $@}, qr{mkpath /A: Permission denied}, 'eval { mkpath "/A/" }; $@   # ~> mkpath /A: Permission denied'; undef $::_g0; undef $::_e0;

mkpath "A///./file";
local ($::_g0 = do {-d "A"}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '-d "A"  # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ### See also
# 
# * [File::Path](https://metacpan.org/pod/File::Path) – `mkpath("dir1/dir2")`.
# * [File::Path::Tiny](https://metacpan.org/pod/File::Path::Tiny) – `File::Path::Tiny::mk($path)`. Не выбрасывает исключений.
# 
# ## mtime (;$path)
# 
# Время модификации `$path` в unixtime с дробной частью (из `Time::HiRes::stat`). Без параметра использует `$_`.
# 
# Выбрасывает исключение, если файл не существует или нет прав:
# 
::done_testing; }; subtest 'mtime (;$path)' => sub { 
local $_ = "nofile";
::like scalar do {eval { mtime }; $@}, qr{mtime nofile: No such file or directory}, 'eval { mtime }; $@  # ~> mtime nofile: No such file or directory'; undef $::_g0; undef $::_e0;

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

# 
# ### See also
# 
# * `-M` – `-M "file.txt"`, `-M _` в днях от текущего времени.
# * [stat](https://metacpan.org/pod/stat) – `(stat "file.txt")[9]` в секундах (unixtime).
# * [Time::HiRes](https://metacpan.org/pod/Time::HiRes) – `(Time::HiRes::stat "file.txt")[9]` в секундах с дробной частью.
# * [Mojo::File](https://metacpan.org/pod/Mojo::File) – `path($file)->stat->mtime`.
# 
# ## sta (;$path)
# 
# Возвращает статистику о файле. Без параметра использует `$_`.
# 
# Чтобы можно было использовать с другими файловыми функциями, может получать ссылку на массив из которого берёт первый элемент в качест...
# 
# Выбрасывает исключение, если файл не существует или нет прав:
# 
::done_testing; }; subtest 'sta (;$path)' => sub { 
local $_ = "nofile";
::like scalar do {eval { sta }; $@}, qr{sta nofile: No such file or directory}, 'eval { sta }; $@  # ~> sta nofile: No such file or directory'; undef $::_g0; undef $::_e0;

::like scalar do {sta(["/"])->{ino}}, qr{^\d+$}, 'sta(["/"])->{ino} # ~> ^\d+$'; undef $::_g0; undef $::_e0;
::like scalar do {sta(".")->{atime}}, qr{^\d+(\.\d+)?$}, 'sta(".")->{atime} # ~> ^\d+(\.\d+)?$'; undef $::_g0; undef $::_e0;

# 
# ### See also
# 
# * [Fcntl](https://metacpan.org/pod/Fcntl) – содержит константы для распознавания режима.
# * [BSD::stat](https://metacpan.org/pod/BSD::stat) – дополнительно возвращает atime, ctime и mtime в наносекундах, флаги пользователя и номер генерации файла. Имеет ОÐ...
# * [File::chmod](https://metacpan.org/pod/File::chmod) – `chmod("o=,g-w","file1","file2")`, `@newmodes = getchmod("+x","file1","file2")`.
# * [File::stat](https://metacpan.org/pod/File::stat) – предоставляет ООП-интерфейс к stat.
# * [File::Stat::Bits](https://metacpan.org/pod/File::Stat::Bits) – аналогичен [Fcntl](https://metacpan.org/pod/Fcntl).
# * [File::stat::Extra](https://metacpan.org/pod/File::stat::Extra) – расширяет [File::stat](https://metacpan.org/pod/File::stat) методами для получения информации о режиме, а так же перезаÐ...
# * [File::Stat::Ls](https://metacpan.org/pod/File::Stat::Ls) – возвращает режим в формате утилиты ls.
# * [File::Stat::Moose](https://metacpan.org/pod/File::Stat::Moose) – ООП интерфейс на Moose.
# * [File::Stat::OO](https://metacpan.org/pod/File::Stat::OO) – предоставляет ООП-интерфейс к stat. Может возвращать atime, ctime и mtime сразу в `DateTime`.
# * [File::Stat::Trigger](https://metacpan.org/pod/File::Stat::Trigger) – следилка за изменением атрибутов файла.
# * [Linux::stat](https://metacpan.org/pod/Linux::stat) – парсит /proc/stat и возвращает доп-информацию. Однако в других ОС не работает.
# * [Stat::lsMode](https://metacpan.org/pod/Stat::lsMode) – возвращает режим в формате утилиты ls.
# * [VMS::Stat](https://metacpan.org/pod/VMS::Stat) – возвращает списки VMS ACL.
# 
# ## path (;$path)
# 
# Разбивает файловый путь на составляющие или собирает его из составляющих.
# 
# * Если получает ссылку на массив, то воспринимает его первый элемент как путь.
# * Если получает ссылку на хэш, то собирает из него путь. Незнакомые ключи просто игнорирует. Набор ключей для каждой ФС – разный.
# * ФС берётся из системной переменной `$^O`.
# * К файловой системе не обращается.
# 
::done_testing; }; subtest 'path (;$path)' => sub { 
{
    local $^O = "freebsd";

local ($::_g0 = do {path "."}, $::_e0 = do {{path => ".", file => ".", name => "."}}); ::is_deeply $::_g0, $::_e0, '    path "."        # --> {path => ".", file => ".", name => "."}' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e...
local ($::_g0 = do {path ".bashrc"}, $::_e0 = do {{path => ".bashrc", file => ".bashrc", name => ".bashrc"}}); ::is_deeply $::_g0, $::_e0, '    path ".bashrc"  # --> {path => ".bashrc", file => ".bashrc", name => ".bashrc"}' or ::diag ::_struct_diff(...
local ($::_g0 = do {path ".bash.rc"}, $::_e0 = do {{path => ".bash.rc", file => ".bash.rc", name => ".bash", ext => "rc"}}); ::is_deeply $::_g0, $::_e0, '    path ".bash.rc"  # --> {path => ".bash.rc", file => ".bash.rc", name => ".bash", ext => "rc"...
local ($::_g0 = do {path ["/"]}, $::_e0 = do {{path => "/", dir => "/"}}); ::is_deeply $::_g0, $::_e0, '    path ["/"]      # --> {path => "/", dir => "/"}' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
    local $_ = "";
local ($::_g0 = do {path}, $::_e0 = do {{path => ""}}); ::is_deeply $::_g0, $::_e0, '    path            # --> {path => ""}' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {path "a/b/c.ext.ly"}, $::_e0 = do {{path => "a/b/c.ext.ly", dir => "a/b", file => "c.ext.ly", name => "c", ext => "ext.ly"}}); ::is_deeply $::_g0, $::_e0, '    path "a/b/c.ext.ly"   # --> {path => "a/b/c.ext.ly", dir => "a/b", fil...

local ($::_g0 = do {path +{dir  => "/", ext => "ext.ly"}}, $::_e0 = "/.ext.ly"); ::ok $::_g0 eq $::_e0, '    path +{dir  => "/", ext => "ext.ly"}    # => /.ext.ly' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {path +{file => "b.c", ext => "ly"}}, $::_e0 = "b.ly"); ::ok $::_g0 eq $::_e0, '    path +{file => "b.c", ext => "ly"}      # => b.ly' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {path +{path => "a/b/f.c", dir => "m"}}, $::_e0 = "m/f.c"); ::ok $::_g0 eq $::_e0, '    path +{path => "a/b/f.c", dir => "m"}   # => m/f.c' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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


local ($::_g0 = do {path {volume => "ADFS::HardDisk.", file => "File"}}, $::_e0 = 'ADFS::HardDisk.File'); ::ok $::_g0 eq $::_e0, '    path {volume => "ADFS::HardDisk.", file => "File"} # \> ADFS::HardDisk.File' or ::diag ::_string_diff($::_g0, $::_e0...
local ($::_g0 = do {path {volume => "ADFS::HardDisk.", folder => '$', file => "File"}}, $::_e0 = 'ADFS::HardDisk.$.File'); ::ok $::_g0 eq $::_e0, '    path {volume => "ADFS::HardDisk.", folder => \'$\', file => "File"} # \> ADFS::HardDisk.$.File' or ...
local ($::_g0 = do {path {folder => "x"}}, $::_e0 = "x."); ::ok $::_g0 eq $::_e0, '    path {folder => "x"}  # => x.' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {path {dir    => "x."}}, $::_e0 = "x."); ::ok $::_g0 eq $::_e0, '    path {dir    => "x."} # => x.' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}

{
    local $^O = "MacOS";

    my $path = {
        path   => '::::mix:report.doc',
        dir    => "::::mix:",
        folder => ":::mix",
        file   => "report.doc",
        name   => "report",
        ext    => "doc",
    };

local ($::_g0 = do {path $path->{path}}, $::_e0 = do {$path}); ::is_deeply $::_g0, $::_e0, '    path $path->{path} # --> $path' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {path $path}, $::_e0 = "$path->{path}"); ::ok $::_g0 eq $::_e0, '    path $path         # => $path->{path}' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {path 'report'}, $::_e0 = do {{path => 'report', file => 'report', name => 'report'}}); ::is_deeply $::_g0, $::_e0, '    path \'report\' # --> {path => \'report\', file => \'report\', name => \'report\'}' or ::diag ::_struct_diff($...

local ($::_g0 = do {path {volume => "x", file => "f"}}, $::_e0 = "x:f"); ::ok $::_g0 eq $::_e0, '    path {volume => "x", file => "f"} # => x:f' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {path {folder => "x"}}, $::_e0 = "x:"); ::ok $::_g0 eq $::_e0, '    path {folder => "x"} # => x:' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}

{
    local $^O = "vmesa";

    my $path = {
        path   => ' USERID   FILE EXT   VOLUME ',
        userid => "USERID",
        file   => "FILE EXT",
        name   => "FILE",
        ext    => "EXT",
        volume => "VOLUME",
    };

local ($::_g0 = do {path $path->{path}}, $::_e0 = do {$path}); ::is_deeply $::_g0, $::_e0, '    path $path->{path} # --> $path' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {path {volume => "x", file => "f"}}, $::_e0 = do {' f  x'}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '    path {volume => "x", file => "f"} # -> \' f  x\'' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0...
}


# 
# ### See also
# 
# * https://en.wikipedia.org/wiki/Path_(computing)
# 
# Модули для определения ОС, а значит и определения, какие в ОС файловые пути:
# 
# * `$^O` – суперглобальная переменная с названием текущей ОС.
# * [Devel::CheckOS](https://metacpan.org/pod/Devel::CheckOS), [Perl::OSType](https://metacpan.org/pod/Perl::OSType) – определяют ОС.
# * [Devel::AssertOS](https://metacpan.org/pod/Devel::AssertOS) – запрещает использовать модуль вне указанных ОС.
# * [System::Info](https://metacpan.org/pod/System::Info) – информация об ОС, её версии, дистрибутиве, CPU и хосте.
# 
# Выделяют части файловых путей:
# 
# * [File::Spec](https://metacpan.org/pod/File::Spec) – `($volume, $directories, $file) = File::Spec->splitpath($path)`. Поддерживает только unix, win32, os/2, vms, cygwin и amigaos.
# * [File::Spec::Functions](https://metacpan.org/pod/File::Spec::Functions) – `($volume, $directories, $file) = splitpath($path)`.
# * [File::Spec::Mac](https://metacpan.org/pod/File::Spec::Mac) – входит в [File::Spec](https://metacpan.org/pod/File::Spec), но не определяется им, поэтому приходится использовать отдельÐ...
# * [File::Basename](https://metacpan.org/pod/File::Basename) – `($name, $path, $suffix) = fileparse($fullname, @suffixlist)`.
# * [Path::Class::File](https://metacpan.org/pod/Path::Class::File) – `file('foo', 'bar.txt')->is_absolute`.
# * [Path::Extended::File](https://metacpan.org/pod/Path::Extended::File) – `Path::Extended::File->new($file)->basename`.
# * [Mojo::File](https://metacpan.org/pod/Mojo::File) – `path($file)->extname`.
# * [Path::Util](https://metacpan.org/pod/Path::Util) – `$filename = basename($dir)`.
# * [Parse::Path](https://metacpan.org/pod/Parse::Path) – `Parse::Path->new(path => 'gophers[0].food.count', style => 'DZIL')->push("chunk")`. Работает с путями как с массивами (`push`, `pop`, `shift`, `splice`). Так ...
# 
# ## transpath ($path?, $from, $to)
# 
# Переводит путь из формата одной ОС в другую.
# 
# Если `$path` не указан, то используется `$_`.
# 
# Перечень поддерживаемых ОС смотрите в примерах подпрограммы `path` чуть выше или так: `keys %Aion::Fs::FS`.
# 
# Названия ОС – регистронезависимы.
# 
::done_testing; }; subtest 'transpath ($path?, $from, $to)' => sub { 
local $_ = ">x>y>z.doc.zip";
local ($::_g0 = do {transpath "vos", "unix"}, $::_e0 = '/x/y/z.doc.zip'); ::ok $::_g0 eq $::_e0, 'transpath "vos", "unix"       # \> /x/y/z.doc.zip' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {transpath "vos", "VMS"}, $::_e0 = '[.x.y]z.doc.zip'); ::ok $::_g0 eq $::_e0, 'transpath "vos", "VMS"        # \> [.x.y]z.doc.zip' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {transpath $_, "vos", "RiscOS"}, $::_e0 = '.x.y.z/doc/zip'); ::ok $::_g0 eq $::_e0, 'transpath $_, "vos", "RiscOS" # \> .x.y.z/doc/zip' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# 
# ## splitdir (;$dir)
# 
# Разбивает директорию на составляющие. Директорию следует вначале получить из `path->{dir}`.
# 
::done_testing; }; subtest 'splitdir (;$dir)' => sub { 
local $^O = "unix";
local ($::_g0 = do {[ splitdir "/x/" ]}, $::_e0 = do {["", "x", ""]}); ::is_deeply $::_g0, $::_e0, '[ splitdir "/x/" ]    # --> ["", "x", ""]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## joindir (;$dirparts)
# 
# Объединяет директорию из составляющих. Затем полученную директорию следует включить в `path +{dir => $dir}`.
# 
::done_testing; }; subtest 'joindir (;$dirparts)' => sub { 
local $^O = "unix";
local ($::_g0 = do {joindir qw/x y z/}, $::_e0 = "x/y/z"); ::ok $::_g0 eq $::_e0, 'joindir qw/x y z/    # => x/y/z' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {path +{ dir => joindir qw/x y z/ }}, $::_e0 = "x/y/z/"); ::ok $::_g0 eq $::_e0, 'path +{ dir => joindir qw/x y z/ } # => x/y/z/' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## splitext (;$ext)
# 
# Разбивает расширение на составляющие. Расширение следует вначале получить из `path->{ext}`.
# 
::done_testing; }; subtest 'splitext (;$ext)' => sub { 
local $^O = "unix";
local ($::_g0 = do {[ splitext ".x." ]}, $::_e0 = do {["", "x", ""]}); ::is_deeply $::_g0, $::_e0, '[ splitext ".x." ]    # --> ["", "x", ""]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## joinext (;$extparts)
# 
# Объединяет расширение из составляющих. Затем полученное расширение следует включить в `path +{ext => $ext}`.
# 
::done_testing; }; subtest 'joinext (;$extparts)' => sub { 
local $^O = "unix";
local ($::_g0 = do {joinext qw/x y z/}, $::_e0 = "x.y.z"); ::ok $::_g0 eq $::_e0, 'joinext qw/x y z/    # => x.y.z' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {path +{ ext => joinext qw/x y z/ }}, $::_e0 = ".x.y.z"); ::ok $::_g0 eq $::_e0, 'path +{ ext => joinext qw/x y z/ } # => .x.y.z' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## include (;$pkg)
# 
# Подключает `$pkg` (если он ещё не был подключён через `use` или `require`) и возвращает его. Без параметра использует `$_`.
# 
# Файл lib/A.pm:
#@> lib/A.pm
#>> package A;
#>> sub new { bless {@_}, shift }
#>> 1;
#@< EOF
# 
# Файл 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` не указан – использует `$_`.
# 
::done_testing; }; subtest 'catonce (;$file)' => sub { 
local $_ = "catonce.txt";
lay "result";
local ($::_g0 = do {catonce}, $::_e0 = do {"result"}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'catonce  # -> "result"' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {catonce}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'catonce  # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

::like scalar do {eval { catonce[] }; $@}, qr{catonce not use ref path\!}, 'eval { catonce[] }; $@ # ~> catonce not use ref path!'; undef $::_g0; undef $::_e0;

# 
# ## wildcard (;$wildcard)
# 
# Переводит файловую маску в регулярное выражение. Без параметра использует `$_`.
# 
# * `**` - `[^/]*`
# * `*` - `.*`
# * `?` - `.`
# * `??` - `[^/]`
# * `{` - `(`
# * `}` - `)`
# * `,` - `|`
# * Остальные символы экранируются с помощью `quotemeta`.
# 
::done_testing; }; subtest 'wildcard (;$wildcard)' => sub { 



( run in 0.659 second using v1.01-cache-2.11-cpan-df04353d9ac )