Aion-Fs
view release on metacpan or search on metacpan
lib/Aion/Fs.pm view on Meta::CPAN
regexp => qr!^
(?<dir>
( (?<volume> [^:]* ) : )?
( (?<folder> .* ) : )?
)
(?<file>
(?<name> [^.:]*? )
( \. (?<ext> [^:]* ) )?
)
\z!xsn,
join => sub {
_join [qw/path dir file/],
volume => "%s:",
folder => "%s:",
name => "%s",
ext => ".%s",
},
},
{
name => VMESA,
symdir => '/',
symext => '.',
regexp => qr!^
\s* (?<userid> \S+ )
\s+ (?<file>
(?<name> \S+ )
\s+ (?<ext> \S+ )
)
\s+ (?<volume> \S+ )
\s*
\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}) {
my $group = $+{group};
if ($group && @S) {
my $curgroup;
for(my $i = $#S; $i>=0; --$i) { $curgroup = $S[$i][1], last if defined $S[$i][1] }
$_->{remove}{$curgroup}{$group}++ if defined $curgroup;
}
push @S, [length($`) + length $&, $group];
}
elsif($+{close}) {
my ($pos, $group, $g2) = @{pop @S};
$S[$#S][2] //= $group if $_->{group}{$group} && @S;
$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? $_: @_;
($dir) = @$dir if ref $dir;
my $fs = _fs;
$dir = $fs->{before_split}->($dir) if exists $fs->{before_split};
split $fs->{symdirquote}, $dir, -1
}
# ÐбÑединÑÐµÑ Ð´Ð¸ÑекÑоÑÐ¸Ñ Ð¸Ð· ÑоÑÑавлÑÑÑиÑ
sub joindir(@) {
join _fs->{symdir}, @_
}
# Ð Ð°Ð·Ð±Ð¸Ð²Ð°ÐµÑ ÑаÑÑиÑение (Ñип Ñайла) на ÑоÑÑавлÑÑÑие
sub splitext(;$) {
my ($ext) = @_ == 0? $_: @_;
($ext) = @$ext if ref $ext;
split _fs->{symextquote}, $ext, -1
}
# ÐбÑединÑÐµÑ ÑаÑÑиÑение (Ñип Ñайла) из ÑоÑÑавлÑÑÑиÑ
sub joinext(@) {
join _fs->{symext}, @_
}
# ÐÑделÑÐµÑ Ð² пÑÑи ÑоÑÑавлÑÑÑие, а еÑли полÑÑÐ°ÐµÑ Ñ
еÑ, Ñо обÑединÑÐµÑ ÐµÐ³Ð¾ в пÑÑÑ
sub path(;$) {
my ($path) = @_ == 0? $_: @_;
my $fs = _fs;
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,
}
lib/Aion/Fs.pm view on Meta::CPAN
[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 !]
my @dirs;
my $iter = find "hello", "-d";
while(<$iter>) {
push @dirs, $_;
}
\@dirs; # --> [qw! hello hello/big hello/small !]
erase reverse find "hello";
-e "hello"; # -> undef
=head1 DESCRIPTION
This module makes it easier to use the file system.
Modules C<File::Path>, C<File::Slurper> and
C<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.
C<Aion::Fs> uses the KISS programming principle - the simpler the better!
The C<IO::All> supermodule is not a competitor to C<Aion::Fs>, because uses an OOP approach, and C<Aion::Fs> is FP.
=over
=item * OOP â object-oriented programming.
=item * FP â functional programming.
=back
=head1 SUBROUTINES/METHODS
=head2 cat ($file)
Reads the file. If no parameter is specified, use C<$_>.
cat "/etc/passwd" # ~> root
C<cat> reads with layer C<:utf8>. But you can specify another layer like this:
lay "unicode.txt", "â¯";
length cat "unicode.txt" # -> 1
length cat["unicode.txt", ":raw"] # -> 3
C<cat> throws an exception if the I/O operation fails:
eval { cat "A" }; $@ # ~> cat A: No such file or directory
=head3 See also
=over
=item * L<autodie> â C<< open $f, "r.txt"; $s = join "", E<lt>$fE<gt>; close $f >>.
=item * L<File::Slurp> â C<read_file('file.txt')>.
=item * L<File::Slurper> â C<read_text('file.txt')>, C<read_binary('file.txt')>.
=item * L<File::Util> â C<< File::Util-E<gt>new-E<gt>load_file(file =E<gt> 'file.txt') >>.
=item * L<IO::All> â C<< io('file.txt') E<gt> $contents >>.
=item * L<IO::Util> - C<$contents = ${ slurp 'file.txt' }>.
=item * L<Mojo::File> â C<< path($file)-E<gt>slurp >>.
=back
=head2 lay ($file?, $content)
Writes C<$content> to C<$file>.
=over
=item * If one parameter is specified, use C<$_> instead of C<$file>.
=item * C<lay>, uses the C<:utf8> layer. To specify a different layer, use an array of two elements in the C<$file> parameter:
=back
lay "unicode.txt", "â¯" # => unicode.txt
lay ["unicode.txt", ":raw"], "â¯" # => unicode.txt
eval { lay "/", "â¯" }; $@ # ~> lay /: Is a directory
=head3 See also
=over
=item * L<autodie> â C<< open $f, "E<gt>r.txt"; print $f $contents; close $f >>.
=item * L<File::Slurp> â C<write_file('file.txt', $contents)>.
=item * L<File::Slurper> â C<write_text('file.txt', $contents)>, C<write_binary('file.txt', $contents)>.
=item * L<IO::All> â C<< io('file.txt') E<lt> $contents >>.
=item * L<IO::Util> â C<slurp \$contents, 'file.txt'>.
=item * L<File::Util> â C<< File::Util-E<gt>new-E<gt>write_file(file =E<gt> 'file.txt', content =E<gt> $contents, bitmask =E<gt> 0644) >>.
=item * L<Mojo::File> â C<< path($file)-E<gt>spew($chars, 'UTF-8') >>.
( run in 0.420 second using v1.01-cache-2.11-cpan-5b529ec07f3 )