package Math::Farnsworth::Dimension; use strict; use warnings; use Data::Dumper; use List::MoreUtils qw(uniq); sub new { my $class = shift; my $dimers = shift; my $scope = shift; my $dims; { if (defined($dimers)) { $dims = +{%{$dimers}}; #make a shallow copy, i don't feel like debugging this later if somehow i ended up with two objects blessing the same hashref } else { #none, use empty hash $dims = {}; } } my $self = {dimen =>$dims, scope => $scope}; #so i don't have to rewrite a lot of code... NTS: this should probably go away later bless $self; } sub compare { my $self = shift; my $target = shift; # print "DIMENWARN: ".join("::", caller())."\n"; # print Dumper($self, $target); if ((!ref($target)) && keys %{$self->{dimen}} == 0) { return 1; } if (keys %{$target->{dimen}} == keys %{$self->{dimen}}) #check lengths of keys { my $v = 1; for my $k (keys %{$self->{dimen}}) { return 0 if (!exists($target->{dimen}{$k})); #optimization fixes bug! $v = 0 if (($self->{dimen}{$k} != $target->{dimen}{$k}) && ($k ne "string")); } if ($v) #also check if there are no dimensions { return 1; } } return 0; } sub invert { my $self = shift; #i CAN'T modify myself in this! my $atom = $self->new($self->{dimen}); for (keys %{$atom->{dimen}}) { #turn all positives to negatives and vice versa $atom->{dimen}{$_} = -$atom->{dimen}{$_}; } return $atom->prune(); } sub merge { my $self = shift; #i CAN'T modify myself in this! my $atom = Math::Farnsworth::Dimension->new($self->{dimen}); my $partner = shift; my $pd = {}; if (ref($partner) eq "Math::Farnsworth::Dimension") { $pd = $partner->{dimen}; } for (uniq (keys %{$atom->{dimen}}, keys %{$pd})) { no warnings 'uninitialized'; $atom->{dimen}{$_} += $partner->{dimen}{$_}; } return $atom->prune(); } sub mult { my $self = shift; #i CAN'T modify myself in this! my $atom = Math::Farnsworth::Dimension->new($self->{dimen}); my $value = shift; for (keys %{$atom->{dimen}}) { no warnings 'uninitialized'; $atom->{dimen}{$_} *= $value; #this might turn them into Math::PARI objects? does it matter? } return $atom->prune(); } sub prune { my $self = shift; for (keys %{$self->{dimen}}) { if (!$self->{dimen}{$_}) { delete $self->{dimen}{$_}; } } return $self; } 1; # vim: filetype=perl