Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

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?

Well, their existence is documented in Type::Library, the type library base class used by Types::Standard. Any type library built with it will offer is_* variants of type constraints. These functions check their argument and return a boolean indicating whether it passes the type constraint.

The object-oriented way of writing these checks is like this:

use Types::Standard qw(ArrayRef HashRef); if (ArrayRef->check($var)) { ...; } elsif (HashRef->check($var)) { ...; }

Though the object-oriented way is a little slower because it will result in at least three sub calls (including a method call).

The is_* functions should be pretty darn fast, especially if Type::Tiny::XS is installed. Ref::Util::XS is faster, and Params::Util is sometimes faster, but using Type::Library-based type libraries (such as Types::Standard, Types::Common::Numeric, Types::Common::String, Types::Path::Tiny, Types::XSD, etc) will give you a richer selection of types that you can check.


A common use for type checking functions is to do something like:

   is_ArrayRef($var) or die(...);

Type::Library-based type libraries offer a shortcut for this:


The return value of the assert_* functions (if they don't die) is the parameter you passed to them, which makes it convenient to do things like:

use Types::Standard qw(assert_Object assert_ArrayRef); sub process_data { my $self = assert_Object( $_[0] ); my $data = assert_ArrayRef( $_[1] ); ...; }

The object-oriented equivalent of assert_Object($thing) is Object->assert_return($thing). Due to overloading Object->($thing) will also work.


If a type constraint has coercions (like Path from Types::Path::Tiny), there's also a to_* function:

use Types::Path::Tiny qw( to_Path ); my $path = to_Path($thing);

Note that if a coercion fails, there is no exception thrown, and the original value is passed through unaltered. If you want to make sure coercion succeeded:

use Types::Path::Tiny qw( assert_Path to_Path ); my $path = assert_Path( to_Path($thing) );

The object-oriented equivalent of to_Path($thing) is Path->coerce($thing). The object-oriented equivalent of assert_Path(to_Path($thing)) is Path->assert_coerce($thing).

Parameterized Types

It would be pretty cool if you could do:

if (is_ArrayRef[Int]($var)) { ...; }

But that wouldn't be syntactically valid Perl.

You can do this though:

use Types::Standard qw(ArrayRef Int); BEGIN { my $type = ArrayRef->of(Int); *is_ArrayRef_of_Int = $type->compiled_check; *assert_ArrayRef_of_Int = \&{ $type }; *to_ArrayRef_of_Int = sub { $type->coerce(@_) }; } if (is_ArrayRef_of_Int($var)) { ...; }

Exporting Tricks

To export just Object:

   use Types::Standard qw(Object);

To export just is_Object:

   use Types::Standard qw(is_Object);

To export Object and is_Object:

   use Types::Standard qw(Object is_Object);

To export Object and all related functions (is_Object, assert_Object, and to_Object):

   use Types::Standard qw(+Object);

To export Object, ArrayRef, and all the other types:

   use Types::Standard qw(:types);

To export Object, ArrayRef, all the other types, and the related is_* functions:

   use Types::Standard qw(:types :is);

To export Object, ArrayRef, all the other types, and the related is_*, assert_*, and to_* functions:

   use Types::Standard qw(:types :is :assert :to);

In reply to Exploring Type::Tiny Part 4: Using Types::Standard as a Ref::Util-Like Library by tobyink

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2023-11-30 05:13 GMT
Find Nodes?
    Voting Booth?

    No recent polls found