【问题标题】:Moose attribute initializationMoose 属性初始化
【发布时间】:2019-11-15 23:37:15
【问题描述】:

使用 Moose 时自定义初始化某些属性的典型方法是什么?

例如,假设我将两个字符串格式的日期作为班级的输入:

has startdate  => (is => 'ro', isa => 'Str', required => 1);
has enddate    => (is => 'ro', isa => 'Str');

这些日期以字符串形式出现,但我需要将它们格式化为特定日期格式 (ISO8601),如果没有 Moose,我只会在 new() 中初始化它们,但我不确定是否使用 Moose。

阅读文档的可行选项似乎是BUILDARGSBUILD 或使用强制。鉴于我有一个函数 _format_as_iso8601() 可以获取日期并以正确的格式返回它,其中哪一个最合适?

【问题讨论】:

    标签: perl validation moose


    【解决方案1】:

    BUILD 在构造函数之后调用,这样可以方便地验证状态,但不一定对格式化传入参数有用。

    BUILDARGS 允许您在调用构造函数之前修改传入的参数,这使其更适合这种情况。您的属性是只读的,所以这可以工作。

    但是...如果您渴望静态类型,为什么在承诺“这是一个字符串”之后会停下来?如果您为 ISO8601 字符串创建 subtype,您可以承诺“这是一个字符串 并且 它具有 X 格式”。更好的是,您这样做的方式可以立即轻松地移植到其他属性。

    我很怀疑下面的正则表达式是否适合你,但我希望它能说明问题:

    #define the type
    subtype 'iso8601',
        as 'Str',
        where { /\d{4}-\d{2}-\d{2}/ },
        message { "Not a valid ISO8601 string ($_)" };
    
    #provide a coercion
    coerce 'iso8601',
        from 'Str',
        via { _format_as_iso8601 $_ };
    
    #tell moose to coerce the value
    has startdate  => (is => 'ro', isa => 'iso8601', required => 1, coerce => 1);
    

    【讨论】:

    • 谢谢,这正是我希望存在的解决方案类型。
    • My Types::XSD 有一个内置的 Date 类型约束。这是an example coercing from a string。该类型是可参数化的,允许您使用类型约束,例如 Date[minInclusive => '1970-01-01']
    • @tobyink 真的很酷,我肯定会走那条路,这似乎是最灵活的,不用我构建一些东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 2013-12-16
    • 2013-01-06
    • 2017-09-29
    • 2022-01-20
    • 1970-01-01
    相关资源
    最近更新 更多