【发布时间】:2017-06-21 11:26:37
【问题描述】:
我正在构建一个脚本,它递归地构建目录的子目录/文件的名称以及这些子目录中的文件名称作为对象:
package Dir;
use Moose;
use Modern::Perl;
use File;
use strict;
use warnings;
has 'path' => (is => 'ro', isa => 'Str', required => 1);
has 'name' => (is => 'ro', isa => 'Str', lazy => 1, default => sub { my $self = shift; my ($name) = $self->path =~ /\/([^\/]*)$/; return $name; } );
has 'subdirs' => (is => 'rw', isa => 'ArrayRef[Dir]' );
has 'files' => (is => 'rw', isa => 'ArrayRef[File]' );
has 'num_dirs' => (is => 'ro', isa => 'Int', lazy => 1, default => sub { my $self = shift; scalar @{$self->subdirs}; } );
sub BUILD {
my $self = shift;
my $path = $self->path;
# run some tests
logf('Path to the directory does not exist.') if (!-e $path);
logf('The path should point to a directory, not a file.') if (!-d $path);
# populate subdirs attribute with Dir objects
opendir my $dh, $path or die "Can't opendir '$path': $!";
# Get files and dirs and separate them out into categories
my @dirs_and_files = grep { ! m{^\.$|^\.\.$} } readdir $dh;
closedir $dh or die "Can't closedir '$path': $!";
my @subdir_names = grep { -d "$path/$_" } grep { !m{^\.} } @dirs_and_files;
my @file_names = grep { -f "$path/$_" } grep { !m{^\.} } @dirs_and_files;
# Create objects
my @dir_objects = map { Dir->new ( path => $path . '/' . $_ ) } @subdir_names;
my @file_objects = map { File->new ( path => $path . '/' . $_ ) } @file_names;
# Populate this with file and directory objects
$self->subdirs ( \@dir_objects );
$self->files ( \@file_objects );
}
1;
请注意,代码有一个 files 属性,其中包含一个 File 对象数组。 File 具有以下属性:
has 'path' => (is => 'ro', isa => 'Str', required => 1);
has 'name' => (is => 'ro', isa => 'Str', lazy => 1, default => sub { my $self = shift; my ($name) = $self->path =~ /\/([^\/]*)$/; return $name; } );
问题是name 属性在创建File 对象时永远不会设置。我不知道为什么。
编辑 1:解决方案(有点)
所以,我把它拍到File 对象中,看看它是否触发了属性的创建:
sub BUILD {
my $self = shift;
}
这并没有解决问题。但是,这样做了:
sub BUILD {
my $self = shift;
$self->name;
}
不过,我的问题是,为什么我需要这样做?
【问题讨论】:
-
对于 Modern::Perl 和 Moose,严格和警告是多余的。
-
仅供参考,如果您无权访问其父目录,则您错误地声称路径不存在。此外,如果您无权访问其父目录,则您错误地声称该目录的路径不是一个路径。