NAME
Aion::Fs - utilities for the file system: reading, writing, searching, replacing files, etc.
VERSION
0.1.0
SYNOPSIS
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
cat "hello/big/world.txt" # => hello/big/world.txt :utf8 Hellow!
cat "hello/small/world.txt" # => noenter
[find "hello", "*.txt"] # --> [qw! hello/moon.txt hello/world.txt hello/big/world.txt hello/small/world.txt !]
[find "hello", "-d"] # --> [qw! hello hello/big hello/small !]
erase reverse find "hello";
-e "hello" # -> undef
DESCRIPTION
This module makes it easier to use the file system.
Modules File::Path
, File::Slurper
and File::Find
is burdened with various features that are rarely used, but require time to become familiar with and thereby increase the barrier to entry.
Aion::Fs
uses the KISS programming principle - the simpler the better!
The IO::All
supermodule is not a competitor to Aion::Fs
, because uses an OOP approach, and Aion::Fs
is FP.
OOP - object-oriented programming.
FP - functional programming.
SUBROUTINES/METHODS
cat ($file)
Reads the file. If no parameter is specified, uses $_
.
cat "/etc/passwd" # ~> root
cat
reads with layer :utf8
. But you can specify another layer like this:
lay "unicode.txt", "↯";
length cat "unicode.txt" # -> 1
length cat["unicode.txt", ":raw"] # -> 3
cat
throws an exception if the I/O operation fails:
eval { cat "A" }; $@ # ~> cat A: No such file or directory
See also
<autodie> –
open $f, "r.txt"; $s = join "", <$f>; close $f
.<File::Slurp> -
read_file('file.txt')
.<File::Slurper> -
read_text('file.txt')
,read_binary('file.txt')
.<File::Util> -
File::Util->new->load_file(file => 'file.txt')
.<IO::All> -
io('file.txt') > $contents
.<IO::Util> -
$contents = ${ slurp 'file.txt' }
.<Mojo::File> –
path($file)->slurp
.
lay ($file?, $content)
Writes $content
to $file
.
If one parameter is specified, use
$_
instead of$file
.lay
, uses the:utf8
layer. To specify a different layer, use an array of two elements in the$file
parameter:
lay "unicode.txt", "↯" # => unicode.txt
lay ["unicode.txt", ":raw"], "↯" # => unicode.txt
eval { lay "/", "↯" }; $@ # ~> lay /: Is a directory
See also
<autodie> –
open $f, ">r.txt"; print $f $contents; close $f
.<File::Slurp> -
write_file('file.txt', $contents)
.<File::Slurper> -
write_text('file.txt', $contents)
,write_binary('file.txt', $contents)
.<IO::All> -
io('file.txt') < $contents
.<IO::Util> -
slurp \$contents, 'file.txt'
.<File::Util> -
File::Util->new->write_file(file => 'file.txt', content => $contents, bitmask => 0644)
.<Mojo::File> –
path($file)->spew($chars, 'UTF-8')
.
find (;$path, @filters)
Recursively traverses and returns paths from the specified path or paths if $path
is an array reference. Without parameters, uses $_
as $path
.
Filters can be:
By subroutine - the path to the current file is passed to
$_
, and the subroutine must return true or false, as understood by Perl.Regexp - tests each path with a regular expression.
String in the form "-Xxx", where
Xxx
is one or more characters. Similar to Perl operators for testing files. Example:-fr
checks the path with file testers LLhttps://perldoc.perl.org/functions/-X.The remaining lines are turned by the
wildcard
function (see below) into a regular expression to test each path.
Paths that fail the @filters
check are not returned.
If the -X filter is not a perl file function, an exception is thrown:
eval { find "example", "-h" }; $@ # ~> Undefined subroutine &Aion::Fs::h called
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).
Attention! If errorenter
is not specified, then all errors are ignored!
mkpath ["example/", 0];
[find "example"] # --> ["example"]
[find "example", noenter "-d"] # --> ["example"]
eval { find "example", errorenter { die "find $_: $!" } }; $@ # ~> find example: Permission denied
mkpath for qw!ex/1/11 ex/1/12 ex/2/21 ex/2/22!;
my $count = 0;
find "ex", sub { find_stop if ++$count == 3; 1} # -> 2
See also
<AudioFile::Find> - searches for audio files in the specified directory. Allows you to filter them by attributes: title, artist, genre, album and track.
<Directory::Iterator> -
$it = Directory::Iterator->new($dir, %opts); push @paths, $_ while <$it>
.<IO::All> -
@paths = map { "$_" } grep { -f $_ && $_->size > 10*1024 } io(".")->all(0)
.<IO::All::Rule> -
$next = IO::All::Rule->new->file->size(">10k")->iter($dir1, $dir2); push @paths, "$f" while $f = $next->()
.<File::Find> -
find( sub { push @paths, $File::Find::name if /\.png/ }, $dir )
.<File::Find::utf8> - like <File::Find>, only file paths are in utf8.
<File::Find::Age> - sorts files by modification time (inherits <File::Find::Rule>):
File::Find::Age->in($dir1, $dir2)
.<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> - has an OOP interface with an iterator and the
imap
andigrep
functions.<File::Find::Match> - calls a handler for each matching filter. Similar to
switch
.<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 $f = shift; $f->fork(5); tied(@paths)->lock; push @paths, $ f->path; tied(@paths)->unlock })->find; tied(@paths)->remove
.<File::Find::Fast> -
@paths = @{ find($dir) }
.<File::Find::Object> - has an OOP interface with an iterator.
<File::Find::Parallel> - can compare two directories and return their union, intersection and quantitative intersection.
<File::Find::Random> - selects a file or directory at random from the file hierarchy.
<File::Find::Rex> -
@paths = File::Find::Rex->new(recursive => 1, ignore_hidden => 1)->query($dir, qr/^b/i)
.<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, and File::Find::Rule::ImageSize and File::Find::Rule::MMagic extensions:@images = find(file => magic => 'image/*', '!image_x' => '>20', in => '.')
.<File::Find::Wanted> -
@paths = find_wanted( sub { -f && /\.png/ }, $dir )
.<File::Hotfolder> -
watch( $dir, callback => sub { push @paths, shift } )->loop
. Powered byAnyEvent
. Customizable. There is parallelization into several processes.<File::Mirror> - also forms a parallel path for copying files:
recursive { my ($src, $dst) = @_; push @paths, $src } '/path/A', '/path/B'
.<File::Set> -
$fs = File::Set->new; $fs->add($dir); @paths = map { $_->[0] } $fs->get_path_list
.<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, $f while $f = $fw->next
.<File::Wildcard::Find> -
findbegin($dir); push @paths, $f while $f = findnext()
orfindbegin($dir); @paths = findall()
.<File::Util> -
File::Util->new->list_dir($dir, qw/ --pattern=\.txt$ --files-only --recurse /)
.<Mojo::File> –
say for path($path)->list_tree({hidden => 1, dir => 1})->each
.<Path::Find> -
@paths = path_find( $dir, "*.png" )
. For complex queries, use matchable:my $sub = matchable( sub { my( $entry, $directory, $fullname, $depth ) = @_; $depth <= 3 }
.<Path::Extended::Dir> -
@paths = Path::Extended::Dir->new($dir)->find('*.txt')
.<Path::Iterator::Rule> -
$i = Path::Iterator::Rule->new->file; @paths = $i->clone->size(">10k")->all(@dirs); $i->size("<10k")...
.<Path::Class::Each> -
dir($dir)->each(sub { push @paths, "$_" })
.<Path::Class::Iterator> -
$i = Path::Class::Iterator->new(root => $dir, depth => 2); until ($i->done) { push @paths, $i->next->stringify }
.<Path::Class::Rule> -
@paths = Path::Class::Rule->new->file->size(">10k")->all($dir)
.
noenter (@filters)
Tells find
not to enter directories matching the filters behind it.
errorenter (&block)
Calls &block
for every error that occurs when a directory cannot be entered.
find_stop ()
Stops find
being called in one of its filters, errorenter
or noenter
.
my $count = 0;
find "ex", sub { find_stop if ++$count == 3; 1} # -> 2
erase (@paths)
Removes files and empty directories. Returns @paths
. Throws an exception if there is an I/O error.
eval { erase "/" }; $@ # ~> erase dir /: Device or resource busy
eval { erase "/dev/null" }; $@ # ~> erase file /dev/null: Permission denied
See also
unlink
+rmdir
.<File::Path> -
remove_tree("dir")
.<File::Path::Tiny> -
File::Path::Tiny::rm($path)
. Does not throw exceptions.<Mojo::File> –
path($file)->remove
.
replace (&sub, @files)
Replaces each file with $_
if it is modified by &sub
. Returns files that have no replacements.
@files
can contain arrays of two elements. The first is treated as a path and the second as a layer. The default layer is :utf8
.
&sub
is called for each file in @files
. It transmits:
$_
- file contents.$a
— path to the file.$b
— the layer with which the file was read and with which it will be written.
In the example below, the file "replace.ex" is read by the :utf8
layer and written by the :raw
layer in the replace
function:
local $_ = "replace.ex";
lay "abc";
replace { $b = ":utf8"; y/a/¡/ } [$_, ":raw"];
cat # => ¡bc
See also
<File::Edit> –
File::Edit->new($file)->replace('x', 'y')->save
.<File::Edit::Portable> –
File::Edit::Portable->new->splice(file => $file, line => 10, contens => ["line1", "line2"])
.<File::Replace> –
($infh,$outfh,$repl) = replace3($file); while (<$infh>) { print $outfh "X: $_" } $repl->finish
.<File::Replace::Inplace>.
mkpath (;$path)
Like mkdir -p, but considers the last part of the path (after the last slash) to be a filename and does not create it as a directory. Without a parameter, uses $_
.
If
$path
is not specified, use$_
.If
$path
is an array reference, then the path is used as the first element and rights as the second element.The default permission is
0755
.Returns
$path
.
local $_ = ["A", 0755];
mkpath # => A
eval { mkpath "/A/" }; $@ # ~> mkpath /A: Permission denied
mkpath "A///./file";
-d "A" # -> 1
See also
<File::Path> -
mkpath("dir1/dir2")
.<File::Path::Tiny> -
File::Path::Tiny::mk($path)
. Does not throw exceptions.
mtime (;$path)
Modification time of $path
in unixtime with fractional part (from Time::HiRes::stat
). Without a parameter, uses $_
.
Throws an exception if the file does not exist or does not have permission:
local $_ = "nofile";
eval { mtime }; $@ # ~> mtime nofile: No such file or directory
mtime ["/"] # ~> ^\d+(\.\d+)?$
See also
-M
—-M "file.txt"
,-M _
in days from the current time.<stat> -
(stat "file.txt")[9]
in seconds (unixtime).<Time::HiRes> -
(Time::HiRes::stat "file.txt")[9]
in seconds with fractional part.<Mojo::File> -
path($file)->stat->mtime
.
sta (;$path)
Returns statistics about the file. Without a parameter, uses $_
.
To be used with other file functions, it can receive a reference to an array from which it takes the first element as the file path.
Throws an exception if the file does not exist or does not have permission:
local $_ = "nofile";
eval { sta }; $@ # ~> sta nofile: No such file or directory
sta(["/"])->{ino} # ~> ^\d+$
sta(".")->{atime} # ~> ^\d+(\.\d+)?$
See also
<Fcntl> – contains constants for mode recognition.
<BSD::stat> - optionally returns atime, ctime and mtime in nanoseconds, user flags and file generation number. Has an OOP interface.
<File::chmod> –
chmod("o=,g-w","file1","file2")
,@newmodes = getchmod("+x","file1","file2")
.<File::stat> – provides an OOP interface to stat.
<File::Stat::Bits> – similar to <Fcntl>.
<File::stat::Extra> – extends <File::stat> with methods to obtain information about the mode, and also reloads -X, <=>, cmp and ~~ operators and stringified.
<File::Stat::Ls> – returns the mode in the format of the ls utility.
<File::Stat::Moose> – OOP interface for Moose.
<File::Stat::OO> – provides an OOP interface to stat. Can return atime, ctime and mtime at once in
DateTime
.<File::Stat::Trigger> – monitors changes in file attributes.
<Linux::stat> – parses /proc/stat and returns additional information. However, it does not work on other OSes.
<Stat::lsMode> – returns the mode in the format of the ls utility.
<VMS::Stat> – returns VMS ACLs.
path (;$path)
Splits a file path into its components or assembles it from its components.
If it receives a reference to an array, it treats its first element as a path.
If it receives a link to a hash, it collects a path from it. Unfamiliar keys are simply ignored. The set of keys for each FS is different.
FS is taken from the system variable
$^O
.The file system is not accessed.
{
local $^O = "freebsd";
path "." # --> {path => ".", file => ".", name => "."}
path ".bashrc" # --> {path => ".bashrc", file => ".bashrc", name => ".bashrc"}
path ".bash.rc" # --> {path => ".bash.rc", file => ".bash.rc", name => ".bash", ext => "rc"}
path ["/"] # --> {path => "/", dir => "/"}
local $_ = "";
path # --> {path => ""}
path "a/b/c.ext.ly" # --> {path => "a/b/c.ext.ly", dir => "a/b", file => "c.ext.ly", name => "c", ext => "ext.ly"}
path +{dir => "/", ext => "ext.ly"} # => /.ext.ly
path +{file => "b.c", ext => "ly"} # => b.ly
path +{path => "a/b/f.c", dir => "m"} # => m/f.c
local $_ = +{path => "a/b/f.c", dir => undef, ext => undef};
path # => f
path +{path => "a/b/f.c", volume => "/x", dir => "m/y/", file => "f.y", name => "j", ext => "ext"} # => m/y//j.ext
path +{path => "a/b/f.c", volume => "/x", dir => "/y", file => "f.y", name => "j", ext => "ext"} # => /y/j.ext
}
{
local $^O = "MSWin32"; # also os2, symbian and dos
path "." # --> {path => ".", file => ".", name => "."}
path ".bashrc" # --> {path => ".bashrc", file => ".bashrc", name => ".bashrc"}
path "/" # --> {path => "\\", dir => "\\", folder => "\\"}
path "\\" # --> {path => "\\", dir => "\\", folder => "\\"}
path "" # --> {path => ""}
path "a\\b\\c.ext.ly" # --> {path => "a\\b\\c.ext.ly", dir => "a\\b\\", folder => "a\\b", file => "c.ext.ly", name => "c", ext => "ext.ly"}
path +{dir => "/", ext => "ext.ly"} # => \\.ext.ly
path +{dir => "\\", ext => "ext.ly"} # => \\.ext.ly
path +{file => "b.c", ext => "ly"} # => b.ly
path +{path => "a/b/f.c", dir => "m/r/"} # => m\\r\\f.c
path +{path => "a/b/f.c", dir => undef, ext => undef} # => f
path +{path => "a/b/f.c", volume => "x", dir => "m/y/", file => "f.y", name => "j", ext => "ext"} # \> x:m\y\j.ext
path +{path => "x:/a/b/f.c", volume => undef, dir => "/y/", file => "f.y", name => "j", ext => "ext"} # \> \y\j.ext
}
{
local $^O = "amigaos";
my $path = {
path => "Work1:Documents/Letters/Letter1.txt",
dir => "Work1:Documents/Letters/",
volume => "Work1",
folder => "Documents/Letters",
file => "Letter1.txt",
name => "Letter1",
ext => "txt",
};
path "Work1:Documents/Letters/Letter1.txt" # --> $path
path {volume => "Work", file => "Letter1.pm", ext => "txt"} # => Work:Letter1.txt
}
{
local $^O = "cygwin";
my $path = {
path => "/cygdrive/c/Documents/Letters/Letter1.txt",
dir => "/cygdrive/c/Documents/Letters/",
volume => "c",
folder => "Documents/Letters",
file => "Letter1.txt",
name => "Letter1",
ext => "txt",
};
path "/cygdrive/c/Documents/Letters/Letter1.txt" # --> $path
path {volume => "c", file => "Letter1.pm", ext => "txt"} # => /cygdrive/c/Letter1.txt
}
{
local $^O = "dos";
my $path = {
path => 'c:\Documents\Letters\Letter1.txt',
dir => 'c:\Documents\Letters\\',
volume => 'c',
folder => '\Documents\Letters',
file => 'Letter1.txt',
name => 'Letter1',
ext => 'txt',
};
path 'c:\Documents\Letters\Letter1.txt' # --> $path
path {volume => "c", file => "Letter1.pm", ext => "txt"} # \> c:Letter1.txt
path {dir => 'r\t\\', file => "Letter1", ext => "txt"} # \> r\t\Letter1.txt
}
{
local $^O = "VMS";
my $path = {
path => "DISK:[DIRECTORY.SUBDIRECTORY]FILENAME.EXTENSION",
dir => "DISK:[DIRECTORY.SUBDIRECTORY]",
volume => "DISK:",
disk => "DISK",
folder => "DIRECTORY.SUBDIRECTORY",
card => "FILENAME.EXTENSION",
file => "FILENAME.EXTENSION",
name => "FILENAME",
ext => "EXTENSION",
};
path "DISK:[DIRECTORY.SUBDIRECTORY]FILENAME.EXTENSION" # --> $path
$path = {
path => 'NODE["account password"]::DISK$USER:[DIRECTORY.SUBDIRECTORY]FILENAME.EXTENSION;7',
dir => 'NODE["account password"]::DISK$USER:[DIRECTORY.SUBDIRECTORY]',
node => "NODE",
accountname => "account",
password => "password",
volume => 'DISK$USER:',
disk => 'DISK',
user => 'USER',
folder => "DIRECTORY.SUBDIRECTORY",
card => "FILENAME.EXTENSION;7",
file => "FILENAME.EXTENSION",
name => "FILENAME",
ext => "EXTENSION",
version => 7,
};
path 'NODE["account password"]::DISK$USER:[DIRECTORY.SUBDIRECTORY]FILENAME.EXTENSION;7' # --> $path
path {volume => "DISK:", file => "FILENAME.pm", ext => "EXTENSION"} # => DISK:FILENAME.EXTENSION
path {user => "USER", folder => "DIRECTORY.SUBDIRECTORY", file => "FILENAME.pm", ext => "EXTENSION"} # \> $USER:[DIRECTORY.SUBDIRECTORY]FILENAME.EXTENSION
}
{
local $^O = "VOS";
my $path = {
path => "%sysname#module1>SubDir>File.txt",
dir => "%sysname#module1>SubDir>",
volume => "%sysname#module1>",
sysname => "sysname",
module => "module1",
folder => "SubDir",
file => "File.txt",
name => "File",
ext => "txt",
};
path $path->{path} # --> $path
path {volume => "%sysname#module1>", file => "File.pm", ext => "txt"} # => %sysname#module1>File.txt
path {module => "module1", file => "File.pm"} # => %#module1>File.pm
path {sysname => "sysname", file => "File.pm"} # => %sysname#>File.pm
path {dir => "dir>subdir>", file => "File.pm", ext => "txt"} # => dir>subdir>File.txt
}
{
local $^O = "riscos";
my $path = {
path => 'Filesystem#Special_Field::DiskName.$.Directory.Directory.File/Ext/Ext',
dir => 'Filesystem#Special_Field::DiskName.$.Directory.Directory.',
volume => 'Filesystem#Special_Field::DiskName.',
fstype => "Filesystem",
option => "Special_Field",
disk => "DiskName",
folder => '$.Directory.Directory',
file => "File/Ext/Ext",
name => "File",
ext => "Ext/Ext",
};
path $path->{path} # --> $path
$path = {
path => '.$.Directory.Directory.',
dir => '.$.Directory.Directory.',
folder => '.$.Directory.Directory',
};
path '.$.Directory.Directory.' # --> $path
path {volume => "ADFS::HardDisk.", file => "File"} # => ADFS::HardDisk.$.File
path {folder => "x"} # => x.
path {dir => "x."} # => x.
}
{
local $^O = "MacOS";
my $path = {
path => '::::mix:report.doc',
dir => "::::mix:",
folder => ":::mix",
file => "report.doc",
name => "report",
ext => "doc",
};
path $path->{path} # --> $path
path $path # => $path->{path}
path 'report' # --> {path => 'report', file => 'report', name => 'report'}
path {volume => "x", file => "f"} # => x:f
path {folder => "x"} # => x:
}
{
local $^O = "vmesa";
my $path = {
path => ' USERID FILE EXT VOLUME ',
userid => "USERID",
file => "FILE EXT",
name => "FILE",
ext => "EXT",
volume => "VOLUME",
};
path $path->{path} # --> $path
path {volume => "x", file => "f"} # -> ' f x'
}
See also
https://en.wikipedia.org/wiki/Path_(computing)
Modules for determining the OS, and therefore determining what file paths are in the OS:
$^O
– superglobal variable with the name of the current OS.<Devel::CheckOS>, <Perl::OSType> – define the OS.
<Devel::AssertOS> – prohibits the use of the module outside the specified OS.
<System::Info> – information about the OS, its version, distribution, CPU and host.
Parts of file paths are distinguished:
<File::Spec> –
($volume, $directories, $file) = File::Spec->splitpath($path)
. Only supports unix, win32, os/2, vms, cygwin and amigaos.<File::Spec::Functions> –
($volume, $directories, $file) = splitpath($path)
.<File::Spec::Mac> - included in <File::Spec>, but not defined by it, so it must be used separately. For mac os version 9.
<File::Basename> –
($name, $path, $suffix) = fileparse($fullname, @suffixlist)
.<Path::Class::File> –
file('foo', 'bar.txt')->is_absolute
.<Path::Extended::File> –
Path::Extended::File->new($file)->basename
.<Mojo::File> –
path($file)->extname
.<Path::Util> –
$filename = basename($dir)
.<Parse::Path> –
Parse::Path->new(path => 'gophers[0].food.count', style => 'DZIL')->push("chunk")
. Works with paths as arrays (push
,pop
,shift
,splice
). It also overloads comparison operators. It has styles:DZIL
,File::Unix
,File::Win32
,PerlClass
andPerlClassUTF8
.
transpath ($path?, $from, $to)
Converts a path from one OS format to another.
If $path
is not specified, $_
is used.
For a list of supported operating systems, see the examples of the path
subroutine just above or like this: keys %Aion::Fs::FS
.
OS names are case insensitive.
local $_ = ">x>y>z.doc.zip";
transpath "vos", "unix" # \> /x/y/z.doc.zip
transpath "vos", "VMS" # \> [.x.y]z.doc.zip
transpath $_, "vos", "RiscOS" # \> .x.y.z/doc/zip
splitdir (;$dir)
Splits a directory into components. The directory should first be obtained from path->{dir}
.
local $^O = "unix";
[ splitdir "/x/" ] # --> ["", "x", ""]
joindir (;$dirparts)
Combines a directory from its components. The resulting directory should then be included in path +{dir => $dir}
.
local $^O = "unix";
joindir qw/x y z/ # => x/y/z
path +{ dir => joindir qw/x y z/ } # => x/y/z/
splitext (;$ext)
Breaks the extension into its components. The extension should first be obtained from path->{ext}
.
local $^O = "unix";
[ splitext ".x." ] # --> ["", "x", ""]
joinext (;$extparts)
Combines an extension from its components. The resulting extension should then be included in path +{ext => $ext}
.
local $^O = "unix";
joinext qw/x y z/ # => x.y.z
path +{ ext => joinext qw/x y z/ } # => .x.y.z
include (;$pkg)
Connects $pkg
(if it has not already been connected via use
or require
) and returns it. Without a parameter, uses $_
.
lib/A.pm file:
package A;
sub new { bless {@_}, shift }
1;
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
catonce (;$file)
Reads the file for the first time. Any subsequent attempt to read this file returns undef
. Used to insert js and css modules into the resulting file. Without a parameter, uses $_
.
$file
can contain arrays of two elements. The first is treated as a path and the second as a layer. The default layer is:utf8
.If
$file
is not specified, use$_
.
local $_ = "catonce.txt";
lay "result";
catonce # -> "result"
catonce # -> undef
eval { catonce[] }; $@ # ~> catonce not use ref path!
wildcard (;$wildcard)
Converts a file mask to a regular expression. Without a parameter, uses $_
.
**
-[^/]*
*
-.*
?
-.
??
-[^/]
{
-(
}
-)
,
-|
Other characters are escaped using
quotemeta
.
wildcard "*.{pm,pl}" # \> (?^usn:^.*?\.(pm|pl)$)
wildcard "?_??_**" # \> (?^usn:^._[^/]_[^/]*?$)
Used in filters of the find
function.
See also
<File::Wildcard>.
<String::Wildcard::Bash>.
<Text::Glob> -
glob_to_regex("*.{pm,pl}")
.
goto_editor ($path, $line)
Opens the file in the editor from .config at the specified line. Defaults to vscodium %p:%l
.
.config.pm file:
package config;
config_module 'Aion::Fs' => {
EDITOR => 'echo %p:%l > ed.txt',
};
1;
goto_editor "mypath", 10;
cat "ed.txt" # => mypath:10\n
eval { goto_editor "`", 1 }; $@ # ~> `:1 --> 512
from_pkg (;$pkg)
Transfers the packet to the FS path. Without a parameter, uses $_
.
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)
Translates the path from the FS to the package. Without a parameter, uses $_
.
to_pkg "Aion/Fs.pm" # => Aion::Fs
[map to_pkg, "Aion/Fs.md", "A/B/C.md"] # --> ["Aion::Fs", "A::B::C"]
AUTHOR
Yaroslav O. Kosmina mailto:dart@cpan.org
LICENSE
⚖ GPLv3
COPYRIGHT
The Aion::Fs is copyright © 2023 by Yaroslav O. Kosmina. Rusland. All rights reserved.