将受祝福的 CodeRefs 与 Moose 类型约束一起使用

发布于 2024-12-28 22:04:00 字数 804 浏览 3 评论 0原文

我们使用 Moose 类将迭代器序列化为各种输出格式。我们将迭代器描述为一个属性:

has iterator => (
    is => 'ro',
    isa => 'CodeRef',
    required => 1,
);

到目前为止,这工作得很好,但我们最近一直在使用 Iterator::Simple 准备迭代器以供以后使用。这意味着我们可以继续编写以下内容:

has iterator => (
    is => 'ro',
    isa => 'CodeRef|Iterator::Simple::Iterator',
    required => 1,
);

并允许我们的序列化器正确接受迭代器类。然而,这似乎是一个不完整的解决方案。

Moose 有没有办法指定属性必须可调用的约束?我怀疑 Moose::Util::TypeConstraints 并在 &{} 上使用 overload::Overloaded 进行检查,但我想了解是否有人已经创建了一个模块来执行此操作,或者是否有 Moose 标准方法来测试此操作。

We use Moose classes that serialize iterators into various output formats. We describe the iterator as an attribute:

has iterator => (
    is => 'ro',
    isa => 'CodeRef',
    required => 1,
);

This has worked fine so far, but we have lately been using Iterator::Simple to prepare iterators for later consumption. This means that we can go about writing this:

has iterator => (
    is => 'ro',
    isa => 'CodeRef|Iterator::Simple::Iterator',
    required => 1,
);

And allow our serializers to accept the iterator class correctly. However, that seems to be a incomplete solution.

Is there a way in Moose to specify the constraint that the attribute must be callable? I suspect it may be possible with Moose::Util::TypeConstraints and using overload::Overloaded on &{} to check, but I'd like to know if anyone has created a module to do this already or if there is a Moose-standard way to test for this.

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

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

发布评论

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

评论(2

鹤仙姿 2025-01-04 22:04:00

CodeRef 只允许未受祝福的代码引用。幸运的是,创建自己的类型很容易。

如下所示定义 Callable,然后使用它代替 CodeRef。它允许以下操作:

  • 不受欢迎的代码引用。
  • 有福的代码参考。
  • 伪装成代码引用的对象(即那些重载 &{} 的对象)。
use Moose::Util::TypeConstraints;
use overload     qw( );
use Scalar::Util qw( );

subtype 'Callable'
    => as 'Ref'
    => where {
          Scalar::Util::reftype($_) eq 'CODE'
             ||
          Scalar::Util::blessed($_) && overload::Method($_, "&{}")
       }

    # Written such that parent's inline_as needs not be prepended.
    => inline_as {'(
          (Scalar::Util::reftype('.$_[1].') // "") eq 'CODE'
             ||
          Scalar::Util::blessed('.$_[1].') && overload::Method('.$_[1].', "&{}")
       )'};

no Moose::Util::TypeConstraints;

CodeRef only allows unblessed code references. Fortunately, it's easy to make your own types.

Define Callable as shown below, then use it instead of CodeRef. It allows the following:

  • Unblessed code references.
  • Blessed code references.
  • Objects that pretend to be code references (i.e. those that overload &{}).

use Moose::Util::TypeConstraints;
use overload     qw( );
use Scalar::Util qw( );

subtype 'Callable'
    => as 'Ref'
    => where {
          Scalar::Util::reftype($_) eq 'CODE'
             ||
          Scalar::Util::blessed($_) && overload::Method($_, "&{}")
       }

    # Written such that parent's inline_as needs not be prepended.
    => inline_as {'(
          (Scalar::Util::reftype('.$_[1].') // "") eq 'CODE'
             ||
          Scalar::Util::blessed('.$_[1].') && overload::Method('.$_[1].', "&{}")
       )'};

no Moose::Util::TypeConstraints;
撧情箌佬 2025-01-04 22:04:00

您知道如何从 Scalar::Util::reftype 获取足够的信息吗?

Do you know enough to get from Scalar::Util::reftype?

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