1
0
Fork 0
mirror of https://github.com/perlbot/perlbuut synced 2025-06-08 14:05:40 -04:00
perlbuut/deps/Math/Farnsworth/Units.pm
2009-12-05 00:02:04 -05:00

134 lines
2.9 KiB
Perl

package Math::Farnsworth::Units;
use strict;
use warnings;
use Data::Dumper;
use Math::Farnsworth::Value::Pari;
use Math::Pari;
use Math::Farnsworth::Output;
sub new
{
#i should make a constructor that copies, but that'll come later
my $self = {units=>{1=>new Math::Farnsworth::Value::Pari(1)}, dimens=>{}}; #hack to make things work right
bless $self;
}
sub addunit
{
my $self = shift;
my $name = shift;
my $value = shift;
$self->{units}{$name} = $value;
$self->{units}{$name."s"} = $value; #HACK!
}
sub getunit
{
my $self = shift;
my $name = shift;
my $return;
if ($self->_isunit($name))
{
$return = $self->{units}{$name};
}
elsif ($self->hasprefix($name))
{
my ($preval, undef, $realname) = $self->getprefix($name);
# print "GETTING PREFIXES: $name :: $preval :: $realname ::".Dumper($preval, $realname) if (($name eq "mg") || ($name eq "l") || $name eq "milli");
$return = $preval * $self->{units}{$realname};
}
# print "GETTING UNIT: $name : $return : ".Dumper($return) if (($name eq "mg") || ($name eq "l") || $name eq "milli");
return $return;
}
sub hasprefix
{
my $self = shift;
my $name = shift;
#sort them by length, solves issues with longer ones not being found first
my @keys = keys %{$self->{prefix}};
for my $pre (sort {length($b) <=> length($a)} @keys)
{
if ($name =~ /^\Q$pre\E(.*)$/)
{
return 1 if ($self->_isunit($1) || !length($1));
}
}
return 0; #no prefix!
}
sub getprefix
{
my $self = shift;
my $name = shift;
#sort them by length, solves issues with longer ones not being found first
for my $pre (sort {length($b) <=> length($a)} keys %{$self->{prefix}})
{
#print "CHECKING PREFIX: $pre\n" if ($name eq "mg");
if ($name =~ /^\Q$pre\E(.*)$/)
{
my $u = $1;
#print "FOUND: $name == $pre * $u\n";
#print Dumper($self->{prefix}{$pre}) if ($name eq "mg");
$u = 1 unless length($1); #to make certain things work right
return ($self->{prefix}{$pre},$pre,$u) if ($self->_isunit($1) || !length($1));
}
}
return undef; #to cause errors when not there
}
sub isunit
{
my $self = shift;
my $name = shift;
return $self->hasprefix($name) || $self->_isunit($name);
}
sub _isunit
{
my $self = shift;
my $name = shift;
return exists($self->{units}{$name});
}
sub adddimen
{
my $self = shift;
my $name = shift;
my $default = shift; #primitive unit for the dimension, all other units are defined against this
my $val = new Math::Farnsworth::Value::Pari(1, {$name => 1}); #i think this is right
Math::Farnsworth::Output::addcombo($name,$val);
$self->{dimens}{$name} = $default;
$self->addunit($default, $val);
}
#is this useful? yes, need it for display
sub getdimen
{
my $self = shift;
my $name = shift;
return $self->{dimens}{$name};
}
sub setprefix
{
my $self = shift;
my $name = shift;
my $value = shift;
#print "SETTING PREFIX: $name : $value\n" if ($name eq "m");
$self->{prefix}{$name} = $value;
}
1;