Type-Tiny Archives

Using Type::Params Effectively

One of the modules bundled with Type::Tiny is Type::Params, a module that allows you to validate subroutine signatures using type constraints. It's one of the more popular parts of the suite.

This article provides a few hints for using it effectively.

Type::Tiny v2 is Coming

Eagle-eyed watchers of CPAN may have noticed that I've recently been releasing Type::Tiny development releases with version numbers 1.999_XYZ.

Type::Tiny v2 is intended to be compatible with Type::Tiny v1. If you've used Type::Tiny v1, you shouldn't need to change any code, but Type::Tiny v2 has a few new features which may make your code simpler, more maintainable, and more readable if you adopt them.

RFC: new API for Type::Params

Firstly, I'm not planning on breaking compatibility with Type::Params. The new API would live under a different namespace, such as Type::Params2.

The API for Type::Params is currently:

use feature 'state';
use Type::Params qw( compile compile_named_oo );
use Types::Standard -types;

sub function_with_positional_parameters {
  state $check = compile( ArrayRef, Int, Int );
  my ( $list, $start, $end ) = $check->( @_ );

  my @slice = @{$list}[ $start .. $end ];
  return \@slice;
}

sub function_with_na…

Zydeco::Lite

Today I released Zydeco::Lite, a re-implementation of Zydeco but just using standard Perl syntax. So for example, class { ... } becomes class(sub { ...});.

This has the advantage of much faster compile time, similar run time speed, fewer dependencies, and compatibility with older versions of Perl before the keyword API was introduced. Of course, in some circumstances these aren't important concerns, so the nicer syntax of the full Zydeco will be preferred.

Zydeco and Zydeco::Lite are both based on MooX::Press which itself is based on Moo, Type::Tiny, and other modules. I've taken the synopsis example from the Zydeco documentation and rewritten it using the different layers of abstraction.

Thoughts on Marshalling and Unmarshalling in Zydeco

Prompted by a recent question on PerlMonks, I've been thinking a bit recently on marshalling and unmarshalling Perl objects. If you're happy using Data::Dumper's format, then it's trivial, but today we're looking at JSON.

If you just want to encode your objects as JSON, that's very easy. Just add a TO_JSON method to all your classes. This can be done in a role to eliminate duplication, and in most cases can be as simple as:

The difficulty comes in going the other direction.

Let Mom Help You With Object-Oriented Programming

Mom is a shortcut for creating Moo classes (and roles). It allows you to define a Moo class with the brevity of Class::Tiny. (In fact, Mom is even briefer.)

A simple example:

Announcing Zydeco

Technically, I already announced it, but now I've renamed it. MooX::Pression is now called Zydeco.

Moops had a memorable name, and I think the naming really helped it gain a following. MooX::Pression was just meh. So now it's Zydeco. Zydeco is a fun word and pretty short to type. It's a musical genre that blends jazz, blues, and Louisiana French Creole, and it just seemed like a good fit for a module that takes what I feel are some of the coolest features of Perl programming, and blen…

MooX::Pression — now much faster

The test suite for MooX::Pression used to run in 79 seconds on my laptop. Now it's at 10 seconds.

And no, I didn't cut out any tests — I switched from using Keyword::Declare to a combination of Keyword::Simple and PPR. (Keyword::Declare is a wrapper around Keyword::Simple and PPR, but I found out by using them directly, I could massively improve compile-time speed.)

MooX::Pression allows you to build classes and roles with multimethods, types, method signatures, and sweet, sweet, sugary syntax…

Announcing MooX::Pression

Kind of like Moops but with less hacky parsing.

Type::Tiny 1.8.0 released

Type::Tiny 1.8.0 (1.008000) was released today.

  • Type::Tiny 1.8.0 on MetaCPAN
  • Type::Tiny website (NEW!)
  • The new features are pretty minor. Most of the improvements are in documentation and testing.

    • Totally rewritten manual/tutorial.

    • Every issue on RT has been handled.

    • Bigger test suite. The exact number of tests run varies based on the availability of optional dependencies, but I just ran the test suit…

    Feedback sought

    I've been trying to update the docs for Type::Tiny and want feedback. Is there anything that's hard to understand, or needs explaining more?

    In particular, it's Type::Tiny::Manual and the other pod pages in that namespace that I'm working on.

    Announcing MooX::Press

    MooX::Press is a quick way of building a bunch of Moo roles and classes in one use statement.

    The most basic example would be:

      package MyApp {
        use MooX::Press class => ['Foo', 'Bar'];
      }
      
      my $thing1 = MyApp::Foo->new();
      my $thing2 = MyApp->new_foo();   # alternative constructor

    But do-nothing classes with a constructor and nothing else aren't very exciting. Let's define a class with some subclasses which have attributes and roles and methods and stuff.

    Exploring Type::Tiny Part 7: Creating a Type Library with Type::Library

    Type::Tiny is probably best known as a way of having Moose-like type constraints in Moo, but it can be used for so much more. This is the seventh in a series of posts showing other things you can use Type::Tiny for. This article along with the earlier ones in the series can be found on my blog and in the Cool Uses for Perl section of PerlMonks.

    For small projects, the type constraints in Types::Standard and other CPAN type libraries are probably enough to satisfy your needs. You can do things like:

       use Types::Common::Numeric qw(PositiveInt);
       
       has user_id => (
          is   => 'ro',
          isa  => PositiveInt,
       );

    However for larger apps, say you need to check user identity numbers in an handful of places throughout your code and you use PositiveInt everywhere, then if you ever feel the need to change the constraint for them, you'll need to hunt through your code to look for every use of PositiveInt, make sure it's not being used for some other reason (like to check an age or a counter), and update it.

    So it is helpful to make your own application-specific type library. You can define your own UserId type constraint, and use that everywhere. If the format of your identifiers ever changes, you only need to change the definition of the type constraint.

    Exploring Type::Tiny Part 6: Some Interesting Type Libraries

    Type::Tiny is probably best known as a way of having Moose-like type constraints in Moo, but it can be used for so much more. This is the sixth in a series of posts showing other things you can use Type::Tiny for. This article along with the earlier ones in the series can be found on my blog and in the Cool Uses for Perl section of PerlMonks.

    While Types::Standard provides all the type constraints Moose users will be familiar with (and a few more) there are other type libraries you can use instead of or as well as Types::Standard.

    Exploring Type::Tiny Part 5: match_on_type

    Type::Tiny is probably best known as a way of having Moose-like type constraints in Moo, but it can be used for so much more. This is the fifth in a series of posts showing other things you can use Type::Tiny for. This article along with the earlier ones in the series can be found on my blog and in the Cool Uses for Perl section of PerlMonks.

    It's pretty common to do things like this:

       use Types::Standard qw( is_ArrayRef is_HashRef );
       use Carp qw( croak );
       
       sub process_data {
          my ($self, $data) = @_;
          if (is_ArrayRef($data)) {
             $self->_process_value($_) for @$data;
          }
          elsif (is_HashRef($data)) {
             $self->_process_value($_) for values %$data;
          }
          else {
             croak "Could not grok data";
          }
       }

    Type::Utils provides a perhaps slightly neater way to do this:

    Exploring Type::Tiny Part 4: Using Types::Standard as a Ref::Util-Like Library

    Type::Tiny is probably best known as a way of having Moose-like type constraints in Moo, but it can be used for so much more. This is the third in a series of posts showing other things you can use Type::Tiny for. This article along with part 1, part 2, and part 3 can be found on my blog and in the Cool Uses for Perl section of PerlMonks.

    Even if you read the documentation of Types::Standard pretty thoroughly, you'd probably miss that you can do things like this:

       use Types::Standard qw(is_ArrayRef is_HashRef);
       
       if (is_ArrayRef($var)) {
          ...;
       }
       elsif (is_HashRef($var)) {
          ...;
       }

    It is documented that Types::Standard exports functions called ArrayRef and HashRef, which are constant-like functions returning Moose/Moo-compatible type constraint objects, but where did these is_ArrayRef and is_HashRef functions come from?

    Exploring Type::Tiny Part 3: Using Type::Tie

    Type::Tiny is probably best known as a way of having Moose-like type constraints in Moo, but it can be used for so much more. This is the third in a series of posts showing other things you can use Type::Tiny for. This article along with part 1 and part 2 can be found on my blog and in the Cool Uses for Perl section of PerlMonks.

    This works:

       use Types::Standard qw(Int);
       
       tie(my @numbers, Int);
       
       push @numbers, 1, 2, 3;     # ok
       push @numbers, "four";      # dies

    Well, if you try it, you may find it complains about not being able to load Type::Tie.

    Type::Tie is an add-on for Type::Tiny distributed separately. It's an optional dependency, so if you want to use this feature, you'll need to make sure it's installed.

    Exploring Type::Tiny Part 2: Using Type::Tiny with Moose

    Type::Tiny is probably best known as a way of having Moose-like type constraints in Moo, but it can be used for so much more. This is the second in a series of posts showing other things you can use Type::Tiny for. You can refer back to part 1.

    Type::Tiny is often used in Moo classes and roles as a drop-in replacement for Moose's built-in type system. But the original reason I wrote it was as a response to the growing number of MooseX::Types and MouseX::Types modules on CPAN. I thought "wouldn't it be good if you could write a type library once, and use it for Moose, Mouse, and maybe even Moo?" In the very early version, you needed to import types like this:

       use Type::Standard -moose, qw(Int);
       use Type::Standard -mouse, qw(Int);
       use Type::Standard -moo,   qw(Int);

    Specifying which object system you were using allowed the type library to export different blessed type constraint objects for different object frameworks. Eventually this need was eliminated by having Type::Tiny's objects better mock the Moose and Mouse native APIs, so the frameworks didn't even notice you weren't using their built-in type constraints.

    (While no longer documented, the -moose, etc import flags still work in all Type::Library-based type libraries.)

    Anyway, so now you know Type::Tiny types can work with Moose, what are the reasons to use them over Moose's built-in type constraints?

    Exploring Type::Tiny Part 1: Using Type::Params for Validating Function Parameters

    Type::Tiny is probably best known as a way of having Moose-like type constraints in Moo, but it can be used for so much more. This is the first in a series of posts showing other things you can use Type::Tiny for.

    Let's imagine you have a function which takes three parameters, a colour, a string of text, and a filehandle. Something like this:

      sub htmlprint {
        my %arg = @_;
        $arg{file}->printf(
          '<span style="color:%s">%s</span>',
          $arg{colour},
          $arg{text},
        );
      }

    Nice little function. Simple enough. But if people call it like this:

      htmlprint( file => $fh, text => "Hello world", color => "red" );

    ... then they'll get weird and unexpected behaviour. Have you spotted the mistake?

    What is a Bool?

    Perl allows pretty much any value to be evaluated in a boolean context:

    if ($something) {
       ...
    }

    No matter what $something is, it will safely evaluate to either true or false. (With the exceptions of a few edge cases like blessed objects which are overloaded to throw an error when evaluated as booleans.)

    So when a Moose class does something like this, what does it mean?

    has something => (
       is  => 'ro',
       isa => 'Bool',
    );

    Type::Tiny 1.2.0 Released

    So, Type::Tiny 1.2.0 (a.k.a. 1.002000 using Perlish decimals) is now available on CPAN.

    Highlights since 1.0.0:

    About Toby Inkster

    user-pic I'm tobyink on CPAN, IRC and PerlMonks.