Data::Dumper Debugging
I've never really used the Perl debugger much (maybe I should learn?) and usually resort to lots of use Data::Dumper; print Dumper($somevar);
statements to help me understand what's going wrong with a piece of code.
I've never really used the Perl debugger much (maybe I should learn?) and usually resort to lots of use Data::Dumper; print Dumper($somevar);
statements to help me understand what's going wrong with a piece of code.
In Perl, hashes are typically used for two sorts of purposes: maps (where the hash key acts as an object identifier) and dictionaries (where the hash key acts like a field name). A quick illustration of what I mean by this:
# Maps my %ages = ( alice => 24, bob => 25, carol => 31, ); my %email = ( alice => "alice@example.net", bob => "robert.smith@example.com", carol => "c_jones@example.org", ); # Dictionaries my %alice = ( age => 24, email => "alice@example.net" ); my %bob = ( age => 25, email => "robert.smith@example.com" ); my %carol = ( age => 32, email => "c_jones@example.org" );
These are two different styles of using hashes. Sometimes one is useful, and sometimes the other is. Sometimes neither is better and your choice of one over the other is fairly arbitrary.
Types::Standard contains a type constraint called Map
which is useful for validating references to the first kind of hash. (I copied the idea from MooseX::Types::Structured.) But today I'm mainly going to talk about another type constraint: Dict
. (Yeah, I copied that one too.)
Let's say you want an attribute to accept a pair of numbers - perhaps a geographic co-ordinates [ 50.873, -0.002 ]
. You could constrain the attribute as ArrayRef[Num]
, but that would accept an arrayref containing a single number, or eight numbers, or even a reference to an empty array.
With the Tuple
type constraint, you can be more exact in expressing which values are acceptable:
isa => Tuple[ Num, Num ]
So you have this Moo class, and it turns out what you really need for it is the StrictVersionStr type constraint defined in MooseX::Types::Perl. You could switch the class to Moose, but long term you want to stick with Moo.
Eventually you'll steal what you need from MooseX::Types::Perl, so you don't have the Moose dependency, but for now what you really want is to be able to use a Moose type constraint within a Moo class! What a predicament you've gotten yourself into! Type::Tiny to the rescue!
{ package Local::Eg5; use Moo; use MooseX::Types::Perl qw( StrictVersionStr ); use Types::TypeTiny qw( to_TypeTiny ); has version_number => ( is => "ro", isa => to_TypeTiny( StrictVersionStr ), ); }
If ever you're unsure of how a type constraint has been defined, you can examine the string of Perl code used to implement it. For example, does an ArrayRef[Int]
accept an empty arrayref?
my $type = ArrayRef[Int]; print $type->inline_check('$X');
Here's a quick way to create an attribute that coerces to an integer from any other number:
package Local::Eg3; use Moose; use Types::Standard -types; has foo => ( is => "ro", isa => Int->plus_coercions( Num, sub{int($_)} ), coerce => 1, ); __PACKAGE__->meta->make_immutable;
When you use code like this:
package Local::Eg2; use Moose; use Types::Standard -types; has foo => ( is => "ro", isa => Int, coerce => 1, ); __PACKAGE__->meta->make_immutable;
Perhaps you don't think very much about what that bareword Int
is actually doing. Well, it's a function that returns a blessed object. This object is used by Moose to check whether values are integers. Yes, Moose uses the object, and you can use it too!
Type::Tiny objects overload the &
(bitwise and) operator to build a type constraint intersection. For example:
package Local::Eg1; use Moose; use Types::Standard -types; has foo => ( is => "ro", isa => ArrayRef[Int] & HashRef[Int], ); __PACKAGE__->meta->make_immutable;
Though that example isn't especially useful. Do you remember Venn diagrammes? Intersections are that small overlapping section in the middle. So the value for foo
needs to be something that is simultaneously an arrayref and a hashref. (Which no value could satisfy.)
But there are ways intersections can be used more usefully.
It's been almost 17 months, and over 160 releases to get there, but Type-Tiny 1.000000 has been released on CPAN Day 2014.
Over the next few days I'll be posting some tips and tricks explaini…
Welcome to Planet Moose, a brief write up on what's been happening in the world of Moose in the past month, for the benefit of those of you who don't have their eyes permanently glued to the #moose IRC channel, or the MetaCPAN recent uploads page.
If you'd like to contribute some news for next month's issue, you can do so on the wiki.
Moose 2.1210 has been released containing some updates to the test suite, and documentation improvements.