File-DataClass

 view release on metacpan or  search on metacpan

lib/File/DataClass/IO.pm  view on Meta::CPAN

my $IO_LOCK = enum 'IO_Lock' => [ FALSE, LOCK_BLOCKING, LOCK_NONBLOCKING ];
my $IO_MODE = enum 'IO_Mode' => [ qw( a a+ r r+ w w+ ) ];
my $IO_TYPE = enum 'IO_Type' => [ qw( dir file ) ];

# Attribute constructors
my $_build_dir_pattern = sub {
   my $cd = curdir; my $ud = updir; qr{ \A (?: \Q${cd}\E | \Q${ud}\E ) \z }mx;
};

my $_catfile = sub {
   return File::Spec->catfile( map { defined( $_ ) ? $_ : NUL } @_ );
};

my $_expand_tilde = sub {
  (my $path = $_[ 0 ]) =~ m{ \A ([~] [^/\\]*) .* }mx;

   my ($dir) = glob( $1 ); $path =~ s{ \A ([~] [^/\\]*) }{$dir}mx;

   return $path;
};

my $_coerce_name = sub {
   my $name = shift;

   not defined  $name          and return;
   is_coderef   $name          and $name =  $name->();
   blessed      $name          and $name =  "${name}";
   is_arrayref  $name          and $name =  $_catfile->( @{ $name } );
   first_char   $name eq TILDE and $name =  $_expand_tilde->( $name );
   curdir eq    $name          and $name =  Cwd::getcwd();
   CORE::length $name > 1      and $name =~ s{ [/\\] \z }{}mx;
   return $name;
};

# Public attributes
has 'autoclose'     => is => 'lazy', isa => Bool,           default => TRUE  ;
has 'have_lock'     => is => 'rwp',  isa => Bool,           default => FALSE ;
has 'io_handle'     => is => 'rwp',  isa => Maybe[Object]                    ;
has 'is_open'       => is => 'rwp',  isa => Bool,           default => FALSE ;
has 'mode'          => is => 'rwp',  isa => $IO_MODE | PositiveInt,
   default          => 'r'                                                   ;
has 'name'          => is => 'rwp',  isa => SimpleStr,      default => NUL,
   coerce           => $_coerce_name,                       lazy    => TRUE  ;
has '_perms'        => is => 'rwp',  isa => PositiveInt,    default => PERMS,
   init_arg         => 'perms'                                               ;
has 'reverse'       => is => 'lazy', isa => Bool,           default => FALSE ;
has 'sort'          => is => 'lazy', isa => Bool,           default => TRUE  ;
has 'type'          => is => 'rwp',  isa => Maybe[$IO_TYPE]                  ;

# Private attributes
has '_assert'       => is => 'rw',   isa => Bool,           default => FALSE ;
has '_atomic'       => is => 'rw',   isa => Bool,           default => FALSE ;
has '_atomic_infix' => is => 'rw',   isa => SimpleStr,      default => 'B_*' ;
has '_backwards'    => is => 'rw',   isa => Bool,           default => FALSE ;
has '_block_size'   => is => 'rw',   isa => PositiveInt,    default => 1024  ;
has '_chomp'        => is => 'rw',   isa => Bool,           default => FALSE ;
has '_deep'         => is => 'rw',   isa => Bool,           default => FALSE ;
has '_dir_pattern'  => is => 'lazy', isa => RegexpRef,
   builder          => $_build_dir_pattern                                   ;
has '_filter'       => is => 'rw',   isa => Maybe[CodeRef]                   ;
has '_layers'       => is => 'ro',   isa => ArrayRef[SimpleStr],
   builder          => sub { [] }                                            ;
has '_lock'         => is => 'rw',   isa => $IO_LOCK,       default => FALSE ;
has '_no_follow'    => is => 'rw',   isa => Bool,           default => FALSE ;
has '_separator'    => is => 'rw',   isa => Str,            default => $RS   ;
has '_umask'        => is => 'ro',   isa => ArrayRef[Int],
   builder          => sub { [] }                                            ;

# Construction
my @ARG_NAMES = qw( name mode perms );

my $_clone_one_of_us = sub {
   my ($self, $params) = @_;

   $self->autoclose; $self->reverse; $self->sort; # Force evaluation

   my $clone = { %{ $self }, %{ $params // {} } };
   my $perms = delete $clone->{_perms}; $clone->{perms} //= $perms;

   return $clone;
};

my $_constructor = sub {
   my $self = shift; return (blessed $self)->new( @_ );
};

my $_inline_args = sub {
   my $n = shift; return (map { $ARG_NAMES[ $_ ] => $_[ $_ ] } 0 .. $n - 1);
};

my $_is_one_of_us = sub {
   return (blessed $_[ 0 ]) && $_[ 0 ]->isa( __PACKAGE__ );
};

sub BUILDARGS { # Differentiate constructor method signatures
   my $class = shift; my $n = 0; $n++ while (defined $_[ $n ]);

   return                 ( $n == 0 ) ? { io_handle => IO::Handle->new }
        : $_is_one_of_us->( $_[ 0 ] ) ? $_clone_one_of_us->( @_ )
        :       is_hashref( $_[ 0 ] ) ? { %{ $_[ 0 ] } }
        :                 ( $n == 1 ) ? { $_inline_args->( 1, @_ ) }
        :       is_hashref( $_[ 1 ] ) ? { name => $_[ 0 ], %{ $_[ 1 ] } }
        :                 ( $n == 2 ) ? { $_inline_args->( 2, @_ ) }
        :                 ( $n == 3 ) ? { $_inline_args->( 3, @_ ) }
                                      : { @_ };
}

sub BUILD {
   my $self = shift; my $handle = $self->io_handle;

   not $self->name and $handle and $self->_set_is_open( $handle->opened );

   return;
}

sub clone {
   my ($self, @args) = @_; blessed $self or throw 'Clone is an object method';

   return $self->$_constructor( $self, @args );
}

sub DEMOLISH {
   my ($self, $gd) = @_;

   $gd and return; # uncoverable branch true
   $self->_atomic ? $self->delete : $self->close;



( run in 3.086 seconds using v1.01-cache-2.11-cpan-98e64b0badf )