DEV Community

Cover image for Released 'kura' - Store constraints for Data::Checks, Type::Tiny, Moose and more.
kobaken
kobaken

Posted on • Edited on

2 1

Released 'kura' - Store constraints for Data::Checks, Type::Tiny, Moose and more.

Perl offers several libraries for managing type constraints, such as Data::Checks, Type::Tiny, and Moose. In large projects, you might encounter a mix of different type constraints, reflecting the codebase’s evolution over time. Furthermore, recent Perl versions have introduced projects like Corinna, which focuses on class features, and Oshun, which deals with value checking (with Data::Checks being a prototype from this project). Given these developments, I believed it would be useful to manage multiple type constraints through a unified interface, simplifying the process of staying up-to-date with Perl’s advancements.

To address this, I have released Kura, a tool designed to store and retrieve various type constraints from libraries like Data::Checks, Type::Tiny, and Moose in one central location. “Kura” is the Japanese word for a traditional storehouse.

Data::Checks -----------------> +--------+
                                |        |
Type::Tiny -------------------> |        |
                                |  Kura  | ---> Named Value Constraints!
Moose::Meta::TypeConstraint --> |        |
                                |        |
YourFavoriteConstraint -------> +--------+
Enter fullscreen mode Exit fullscreen mode

The following code is synopsis:

package MyFoo {
    use Data::Checks qw(StrEq);
    use kura Foo => StrEq('foo');
}

package MyBar {
    use Types::Standard -types;
    use kura Bar => Str & sub { $_[0] eq 'bar' };
}

package MyBaz {
    use Moose::Util::TypeConstraints;
    use kura Baz => subtype as 'Str' => where { $_[0] eq 'baz' };
}

package MyQux {
    use kura Qux => sub { $_[0] eq 'qux' };
}

use MyFoo qw(Foo);
use MyBar qw(Bar);
use MyBaz qw(Baz);
use MyQux qw(Qux); # CodeRef converted to Type::Tiny

ok  Foo->check('foo') && !Foo->check('bar') && !Foo->check('baz') && !Foo->check('qux');
ok !Bar->check('foo') &&  Bar->check('bar') && !Bar->check('baz') && !Bar->check('qux');
ok !Baz->check('foo') && !Baz->check('bar') &&  Baz->check('baz') && !Baz->check('qux');
ok !Qux->check('foo') && !Qux->check('bar') && !Qux->check('baz') &&  Qux->check('qux');
Enter fullscreen mode Exit fullscreen mode

The following code shows how Kura can be used. If you manually replace use kura with type, it should read similarly to type declarations in statically typed languages😁

package MyFoo {
   use Types::Standard -types;

   use kura Name  => Str & sub { qr/^[A-Z][a-z]+$/ };
   use kura Level => Int & sub { $_[0] >= 1 && $_[0] <= 100 };

   use kura Charactor => Dict[
      name  => Name,
      level => Level,
   ];
}

package main;
use MyFoo qw(Charactor);

Charactor->check({ name => 'Alice', level => 50 });
Enter fullscreen mode Exit fullscreen mode

Happy Hacking!

https://metacpan.org/release/KFLY/kura-0.01/view/lib/kura.pm

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (3)

Collapse
 
thibaultduponchelle profile image
Tib

👍
How you managed to do that?
In particular I don’t see definition of a check sub in the Kura module?

Collapse
 
kfly8 profile image
kobaken

Constraints code is stored in the caller's @EXPORT_OK.
Below is the relevant code. Does this answer your question?

metacpan.org/release/KFLY/kura-0.0...

    my $code = _constraint_to_code(@_);

    {
        no strict "refs";
        *{"$caller\::$name"} = Sub::Util::set_subname( "$caller\::$name", $code);
        push @{"$caller\::EXPORT_OK"}, $name;
    }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
thibaultduponchelle profile image
Tib

Yes, totally. Thank you

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay