MooseX::Types::NumUnit - Type(s) for using units in Moose
package MyPackage use Moose; use MooseX::Types::NumUnit qw/NumUnit NumSI num_of_unit/; has 'quantity' => ( isa => NumUnit, default => 0 ); has 'si_quantity' => ( isa => NumSI, required => 1 ); has 'length' => ( isa => num_of_unit('m'), default => '1 ft' );
This module provides types (
NumUnit and friends) for Moose which represent physical units. More accurately it provides String to Number coercions, so that even if the user inputs a number with an incorrect (but compatible) unit, it will automatically coerce to a number of the correct unit.
A few things to note: since
NumUnit and friends are subtypes of
Num, a purely numerical value will not be coerced. This is by design, but should be kept in mind. Also
NumUnit and friends are coerced by default (see "AUTOMATIC COERCION").
When set to a true value, a string representing any conversion will be printed to
STDERR during coercion.
Since version 0.02,
MooseX::Types::NumUnit does not provide global types. Rather it has exportable type-like function which behave like types but do not pollute the "type namespace". While they behave like types, remember they are functions and they should not be quoted when called. They are null prototyped though, should they shouldn't (usually) need parenthesis. Futher they are not exported by default and must be requested. For more information about this system see MooseX::Types.
A subtype of
Num which accepts a number with a unit, but discards the unit on coercion to a
Num. This is the parent unit for all other units provided herein. Of course those have different coercions.
A subtype of
NumUnit which coerces to the SI equivalent of the unit passed in (i.e. a number in feet will be converted to a number in meters). In truth it is not strictly the SI equivalent, but whatever Physics::Unit thinks is the base unit. This should always be SI (I hope!).
This module provides functions which return anonymous types which satisfy certain criteria. These functions may be exported on request, but are not exported by default.
Creates an anonymous type which has the given
$unit. If a number is passed in which can be converted to the specified unit, it is converted on coercion. If the number cannot be converted, the value of the attribute is set to
0 and a warning is thrown.
Creates an anonymous type which has the SI equivalent of the given
$unit. This is especially handy for composite units when you don't want to work out by hand what the SI base would be.
As a simple example, if
'ft', numbers passed in will be converted to meters! You see, the unit only helps specify the type of unit, however the SI unit is used. Another way to think of these types is as a resticted
NumSI of a certian quantity, allowing a loose specification.
num_of_unit, if a number is passed in which can be converted to the specified (SI) unit, it is converted on coercion. If the number cannot be converted, the value of the attribute is set to
0 and a warning is thrown.
Since the NumUnit types provided by this module are essentially just
Num types with special coercions, it doesn't make sense to use them without coercions enabled on the attribute. To that end, this module mimics MooseX::AlwaysCoerce, with the exception that it only enables coercion on
NumUnit and its subtypes. To prevent this, manually set
coerce => 0 for a given attribute and it will be left alone, or better yet, just use
Num as the type.
This module relys on Math::Units::PhysicalValue to split the value and the unit, but then (very naively) passes the unit conversion to Physics::Unit which has a concept of a Base Unit. Surely there must be some way to either only rely on one of the two, or to check that the hand-off works correctly.
Joel Berger, <email@example.com>
Copyright (C) 2012 by Joel Berger
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.