Currently:
package Local;
use warnings;
use Moose;
use Method::Signatures::Simple;
use Path::Class::File;
use Path::Class::Dir;
method _build_path_class {
my $str = $self->pathstr;
return Path::Class::Dir->new($str) if (-d $str);
return Path::Class::File->new($str);
}
has 'pathstr' => (is => 'rw', isa => 'Str', required => 1);
has 'path' => (
is => 'rw',
lazy => 1,
isa => 'Object',
builder => '_build_path_class',
);
no Moose;
__PACKAGE__->meta->make_immutable();
1;
It works, therefore
my $d = Local->new(pathstr => '/tmp')->path;
my $f = Local->new(pathstr => "/etc/passwd)->path; #is isa Path::Class::File
We are looking for a solution where instead of two attributes pathstrand there pathwill be only one patha, it should force from Strto:
- Path :: Class :: Dir (if it
Stris a directory) - Path :: Class :: File (in any other case)
Sort of:
package Local;
use warnings;
use Moose;
use Method::Signatures::Simple;
use Path::Class::File;
use Path::Class::Dir;
coerce 'Path::Class::Dir',
from Str, via { Path::Class::Dir->new($_) };
coerce 'Path::Class::Dir',
from Str, via { Path::Class::Fiel->new($_) };
has 'path' => (
is => 'rw',
lazy => 1,
isa => 'Path::Class::File|Path::Class::Dir',
required => 1,
coerce => 1,
);
no Moose;
__PACKAGE__->meta->make_immutable();
1;
Edited, expanded the question - because he received a closed voice "it is not clear what he is asking." Hopefully this is more clear now.
For recording, the working version of Ikegami:
package Ike;
use warnings;
use namespace::sweep;
use Moose;
use Moose::Util::TypeConstraints;
class_type('Path::Class::Entity');
coerce 'Path::Class::Entity',
from 'Str',
via {
if (-d $_) {
Path::Class::Dir->new($_)
} else {
Path::Class::File->new($_)
}
};
has 'path' => (
is => 'rw',
isa => 'Path::Class::Entity',
required => 1,
coerce => 1,
);
__PACKAGE__->meta->make_immutable;
1;
my test program
use strict;
use warnings;
use Path::Class;
use Test::More tests => 8;
use Ike;
my $temp = Path::Class::tempdir(CLEANUP => 1);
my $d1 = dir($temp, "d1");
my $d2 = dir($temp, "d2");
$d1->mkpath;
symlink("$d1", "$d2");
my $f1 = file($temp,'f1');
my $f2 = file($temp,'f2');
$f1->touch;
symlink("$f1", "$f2");
sub getpath { return Ike->new( path => shift )->path; }
isa_ok( getpath( $d1 ), 'Path::Class::Dir' );
isa_ok( getpath( $d2 ), 'Path::Class::Dir' );
isa_ok( getpath( $f1 ), 'Path::Class::File' );
isa_ok( getpath( $f2 ), 'Path::Class::File' );
isa_ok( getpath("$d1"), 'Path::Class::Dir' );
isa_ok( getpath("$d2"), 'Path::Class::Dir' );
isa_ok( getpath("$f1"), 'Path::Class::File' );
isa_ok( getpath("$f2"), 'Path::Class::File' );
result:
1..8
ok 1 - An object of class 'Path::Class::Dir' isa 'Path::Class::Dir'
ok 2 - An object of class 'Path::Class::Dir' isa 'Path::Class::Dir'
ok 3 - An object of class 'Path::Class::File' isa 'Path::Class::File'
ok 4 - An object of class 'Path::Class::File' isa 'Path::Class::File'
ok 5 - An object of class 'Path::Class::Dir' isa 'Path::Class::Dir'
ok 6 - An object of class 'Path::Class::Dir' isa 'Path::Class::Dir'
ok 7 - An object of class 'Path::Class::File' isa 'Path::Class::File'
ok 8 - An object of class 'Path::Class::File' isa 'Path::Class::File'
:)