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 )