Math::Units::PhysicalValue - An OO interface for automatically calculating values with units.
use Math::Units::PhysicalValue; my $exit = new Math::Units::PhysicalValue "10,000 ft"; my $open = "3500 ft"; my $delay = "43 s"; my $dist = $exit - $open; my $rate = $dist / $delay; my $weight = "180 lbs"; my $momentum = ($weight * ( ($exit - $open) / $delay )) + "0 kg*m/s"; print "$momentum\n"; # prints 3,761.82 kg*m/s print ($rate + "0 miles/hour"), "\n" # prints 103.07 miles/hour
In more detail than the synopsis, Math::Units::PhysicalValue (aka PV) keeps track of the units on values that might work in the real world. It splits and stores the value and units separately as an array.
Using operator overloading, you can use them how you'd normally use any numeric value. There are probably more gotchas than I can enumerate, but you should be able to stay out of trouble if you keep string values on the right hand side of operators.
my $example1 = new Math::Units::PhysicalValue "10,000 ft"; my $example2 = "3500 ft"; my $example3 = "1000 ft"; print ($example1 + $example2 + $example3), "\n"; # prints: 13,500 ft print ($example3 + $example2 + $example1), "\n"; # generates an error...
Perl is smart enough to do $example1 and $example2 in any order, but $example3 + $example2 is evaluated as the number 4500 (with no units) before it gets added to $example1 -- where the units won't match!
$example1
$example2
$example3 + $example2
Math::Units can handle them (mostly), but Math::Algebra::Symbols cannot.
my $v1 = new Math::Units::PhysicalValue "1 hour"; my $v2 = new Math::Units::PhysicalValue "2 hours"; my $v3 = $v1 + $v2; my $v4 = $v1 / $v2; print "$v3\n"; # prints 3 hours print "$v4\n"; # prints 0.5 hour/hours .. and that's probably not what you want.
There is a shortcut. You can use Math::Units::PhysicalValue "PV" to import the magical shortcut function. my $v = PV "10,000 ft" is the same as $example1 above. Handy.
Math::Units::PhysicalValue "PV"
my $v = PV "10,000 ft"
my $handy = (PV "8miles") + (PV "72ft"); my $time = PV "90s"; my $fast = $handy / $time; # neato
You can also choose to import "pv" for this.
"pv"
Presently, by default, you can create $wierd_units = PV "5 Saxons"; without any real trouble. When you try to convert it to something real, Math::Units will have an opportunity to complain. If your Saxon units cancel out before Math::Units sees it, though, it's perfectly fine to make it up as you go.
$wierd_units = PV "5 Saxons";
WATCH OUT FOR PLURALS (again) though.
There is a Number::Format object in the head of PV. $PrintPrecision is the precision passed to format_number when PV is evaluated in a string context.
$PrintPrecision
$Math::Units::PhysicalValue::PrintPrecision defaults to 2
$Math::Units::PhysicalValue::PrintPrecision
You can set $Math::Units::PhysicalValue::PrintPrecision = -1 to disable it and lastly, you can set all sorts of format settings like so:
$Math::Units::PhysicalValue::PrintPrecision = -1
$Math::Units::PhysicalValue::fmt = new Number::Format(-thousands_sep => '.', -decimal_point => ',', -int_curr_symbol => 'DEM');
Though, at this time, there's no way to change which format function it uses.
If you want to get the numerical value back out, you can use deunit();
deunit()
my $v = deunit PV("8 miles"); # makes $v = 8;
I introduced a special hack on 12/7/5 to allow you to add ANY PV unit to 0 iff 0 had no units previously. That is:
my $v = 0 + PV("3 ft"); # sets $v = PV("3 ft");
This functions by converting the scalar 0 to 0 ft before adding. If you wish to make sure to raise an error on addition to 0, choose to PV the 0 first.
my $v = PV(0) + PV("3 ft"); # will still raise an error
Paul Miller <jettero@cpan.org>
<jettero@cpan.org>
I am using this software in my own projects... If you find bugs, please please please let me know. If you use this at all, let me know. In fact, feel free to email me for almost any reason. So far, this policy has never been irritating.
Copyright (c) 2009 Paul Miller -- LGPL2
Here's a list of things I'd still like to do.
If you'd like to add a couple, please float me an email.
$value-
(PV("7 m/s") ** 9) ** (1/9)
Concerning metric units, I expected them to work much worse than they do. In fact, they appear to function correctly. If you can produce and examples of failures, please let me know. For now I'm going to assume they work.
Math::Units and Math::Algebra::Symbols do all the real work here.
So really, say thanks to these guys:
Ken Fox <fox ta vulpes.com>
<fox ta vulpes.com>
Philip R Brenan at <philiprbrenan ta yahoo.com>
<philiprbrenan ta yahoo.com>
And here's a nod to Number::Format. I use the module constantly.
William R. Ward, <wrw ta bayview.com>
<wrw ta bayview.com>
perl(1), Math::Units, Math::Algebra::Symbols, Number::Format
To install Math::Units::PhysicalValue, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Math::Units::PhysicalValue
CPAN shell
perl -MCPAN -e shell install Math::Units::PhysicalValue
For more information on module installation, please visit the detailed CPAN module installation guide.