![]() |
|
P is for Practical | |
PerlMonks |
Exploring Type::Tiny Part 4: Using Types::Standard as a Ref::Util-Like Libraryby tobyink (Canon) |
on Aug 12, 2018 at 15:50 UTC ( #1220275=CUFP: 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:
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:
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. AssertionsA 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: assert_ArrayRef($var);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:
The object-oriented equivalent of assert_Object($thing) is Object->assert_return($thing). Due to overloading Object->($thing) will also work. CoercionsIf a type constraint has coercions (like Path from Types::Path::Tiny), there's also a to_* function:
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:
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 TypesIt would be pretty cool if you could do:
But that wouldn't be syntactically valid Perl. You can do this though:
Exporting TricksTo 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);
Back to
Cool Uses for Perl
|
|