I use Moose to write scientific simulations, including one very large simulation with a user api. To this point all of the numerical quantities, kept in attributes, needed to be of
Num type. This always meant an implied covenant between the me and the users, which was to use SI units.
However I have a few quantities that I want to use
eV units, which makes a lot more sense. Therefore I setup a simple type with coercion to accept a string
num eV and coerce it to a number given by
qe * num. This got me to thinking, why can’t I do this for all my units?
To answer this need, I present
MooseX::Types::NumUnit which provides a couple static types, but also provides the function
num_of_unit, which creates anonymous types which will automatically coerce a string to a number of the desired unit. For example:
package MyTest; use Moose; use MooseX::Types::NumUnit qw/num_of_unit/; #$MooseX::Types::NumUnit::Verbose = 1; has 'length' => ( isa => num_of_unit( 'm' ), is => 'rw', default => '1 ft' ); has 'speed' => ( isa => num_of_unit('ft / hour'), is => 'rw', required => 1 ); no Moose; __PACKAGE__->meta->make_immutable; my $test = MyTest->new( speed => '2 m / s' ); print $test->speed, "\n"; print $test->length, "\n"; __END__ prints: 23622.0472440945 0.3048
Now my users can use whichever units they want, and I know that my simulation will see the number in the units system that it needs!