开发者

Moose: injecting parameters into construction

开发者 https://www.devze.com 2023-03-28 05:44 出处:网络
I have a filename attribute that has attached validation. Now when the filename isn\'t specified during construction I want to read it from a configuration file.

I have a filename attribute that has attached validation. Now when the filename isn't specified during construction I want to read it from a configuration file.

subtype 'filename'
        => as 'Str'
        => where { -r $_ }
        => message { "$_ is not a readable file" };

has 'students_file' => ( is => 'rw', isa => 'filename', default => '' );
has 'teach开发者_Go百科ers_file' => ( is => 'rw', isa => 'filename', default => '' );

The issue is that BUILD seems to be run after the validation occurs. All examples of BUILDARGS seem to handle a different way of constructing the object.

So where should I read the configuration and set the attribute?


Give teachers_file and students_file builder methods (or inline default subs) that set them from the config file. The builder will only run if those attributes aren't provided as keys to the constructor (unless you use init_arg => undef to prevent them from being set in the constructor).

If your config is an attribute of its own, with a builder that reads the config file, then you have an ordering problem between config and teachers_file and students_file. You can resolve this by making teachers_file and students_file lazy attributes, which ensures that they won't try to be constructed before the config attribute. However, you may want to make sure that the "foo is not a readable file" error is thrown as early as possible during construction, instead of the first time the attribute is used. You can work around that by adding

sub BUILD {
  my $self = shift;
  $self->teachers_file;
  $self->students_file;
}

which ensures that those attributes are read once (and constructed) before the constructor returns.

0

精彩评论

暂无评论...
验证码 换一张
取 消