我如何需要一个不是属性的 Moose 构造函数参数?

发布于 2024-09-29 06:07:23 字数 210 浏览 6 评论 0原文

我有一个 Moose 对象模块,它应该接受相对较大的数据结构 (ds) 作为其构造函数参数之一。它用于计算对象的一些属性。但是,我不希望将 ds 本身存储为属性——只有在对象构造过程中才需要它。

我想过使用 BUILDARGS 但后来我不确定如何定义 ds 是必需的参数。

我该如何解决这个问题?

I have a Moose object module that should accept a relatively large data structure (ds) as one of its constructor arguments. It is used to calculate some of the object's attributes. However, I do not wish to store ds itself as an attributes -- it is only needed during the construction of the object.

I thought of using BUILDARGS but then I'm not sure how to define that ds is a required argument.

How can I work around this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

往日 2024-10-06 06:07:23

我倾向于有一个构造函数,它只采用从数据结构派生的计算值。然后使用不同的方法将有限的参数加上数据结构作为参数。

sub generate_foo_from_ds {
    my $class = shift; 
    my %arg = @_;

    my $ds = $arg{foo_data};

    # Get attributes from args
    my %attrib;
    for (qw(foo bar baz ) {
        croak "Attrib '$_' is required" unless exists $arg{$_};
        $attrib{$_} = $arg{$_};
    }

    # calculate some more attributes here.
    $attrib{griz} = $ds->{whee} * $ds->{whoosh} / $ds->{whiz}[12];

    my $foo = $class->new( %attrib );

    return $foo;
}

然后让你的对象像这样:

my $foo = Foo->generate_foo_from_ds( foo_data => $bar, foo => 1, bar => 2, baz => 2 );

现在你不必担心奇怪的序列化问题或 BUILDARGS 甚至 BUILD。你有一个简单的方法,仅此而已。

I'd be inclined to have a constructor that takes only the calculated values derived from your data structure. Then use a different method to take limited params plus the data structure as args.

sub generate_foo_from_ds {
    my $class = shift; 
    my %arg = @_;

    my $ds = $arg{foo_data};

    # Get attributes from args
    my %attrib;
    for (qw(foo bar baz ) {
        croak "Attrib '$_' is required" unless exists $arg{$_};
        $attrib{$_} = $arg{$_};
    }

    # calculate some more attributes here.
    $attrib{griz} = $ds->{whee} * $ds->{whoosh} / $ds->{whiz}[12];

    my $foo = $class->new( %attrib );

    return $foo;
}

Then make your objects like so:

my $foo = Foo->generate_foo_from_ds( foo_data => $bar, foo => 1, bar => 2, baz => 2 );

Now you don't have to worry about weird serialization issues or BUILDARGS or even BUILD. You have a simple method and that is all.

笙痞 2024-10-06 06:07:23

您可以使用 BUILDBUILDARGS 来实现此目的。如果不了解更多关于您想要做什么的信息,很难说哪个更好,但我猜 BUILD 会是更好的选择。

sub BUILD {
    my $self = shift;
    my $args = shift;

    my $ds = $args->{ds} or confess "Argument (ds) is required";

    $self->some_attr($ds->{...});
    $self->other_attr($ds->{foo}[3]);
    ...
} # end BUILD

如果您希望 Moose 检查类型并确保它存在,则必须将其设为属性。但你可以在使用后在BUILD方法中清除它。

 has 'ds' => (
     is       => 'ro',
     isa      => 'SomeType',
     required => 1,
     clearer  => '_clear_ds',
 );

sub BUILD {
    my $self = shift;
    my $args = shift;

    my $ds = $self->ds;
    $self->_clear_ds;

    $self->some_attr($ds->{...});
    $self->other_attr($ds->{foo}[3]);
    ...
} # end BUILD

如果您愿意,您可以将 reader 方法命名为其他名称(例如 _ds)。

You could use either BUILD or BUILDARGS for this. It's hard to say which would be better without knowing more about what you're trying to do, but I'd guess BUILD would be the better choice.

sub BUILD {
    my $self = shift;
    my $args = shift;

    my $ds = $args->{ds} or confess "Argument (ds) is required";

    $self->some_attr($ds->{...});
    $self->other_attr($ds->{foo}[3]);
    ...
} # end BUILD

If you want Moose to check the type and ensure it's present, you have to make it an attribute. But you can clear it in the BUILD method after you use it.

 has 'ds' => (
     is       => 'ro',
     isa      => 'SomeType',
     required => 1,
     clearer  => '_clear_ds',
 );

sub BUILD {
    my $self = shift;
    my $args = shift;

    my $ds = $self->ds;
    $self->_clear_ds;

    $self->some_attr($ds->{...});
    $self->other_attr($ds->{foo}[3]);
    ...
} # end BUILD

You could name the reader method something else (like _ds) if you wanted to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文