NAME
Physics::Unit::Scalar
DESCRIPTION
This package encapsulates information about physical quantities. Each instance of a class that derives from Physics::Unit::Scalar holds the value of some type of measurable quantity. When you use this module, several new classes are immediately available. See the Derived Classes section below for a complete list.
You will probably only need to use these classes that derive from Physics::Unit::Scalar, such as Physics::Unit::Distance, Physics::Unit::Speed, etc. Of course, you are also free to define your own derived classes, based on types of physical quantities.
This module relies heavily on the Physics::Unit module. Each Scalar object has a Unit object that defines the dimensionality of the Scalar. The dimensionality also defines (more or less) the type of physical quantity that is stored. The type of physical quantity (that is, the type of the Unit object) corresponds to the derived class to which the object belongs.
For example, the class Physics::Unit::Distance uses the Physics::Unit object named 'meter' to define the scale of its object instances. Coincidentally (not really) the type of the Unit object is 'Distance'.
Defining classes that correspond to physical quantity types allows us to overload the arithmetic methods to produce derived classes of the correct type automagically.
In general, when a new Physics::Unit::Scalar needs to be created as the result of some operation, this package attempts determine its subclass based on its dimensionality. Thus, when you multiply two Distances together, the result is an Area object. This behavior can be selectively overridden when necessary.
The class was designed this way in order to minimize the programmer's need to keep track of the various physical types of the objects in use, and to enable the compiler, in many cases, to verify computations on the basis of dimensional analysis. Yet, there needs to be mechanisms to overide the default behavior in many cases. For example, both energy and torque have the same dimensions: Force * Distance. Therefore, it remains the programmer's responsibility, in this case, to assign the correct subclass to Scalars that have this dimensionality.
SYNOPSIS
use Physics::Unit::Scalar;
# Manipulate Distances
$d = new Physics::Unit::Distance('98 mi');
print $d->ToString, "\n"; # prints '157715.712 meter'
$d->add('10 km');
print "Sum is ", $d->ToString, "\n"; # prints '167715.712 meter'
print $d->value, ' ', $d->default_unit->name, "\n"; # same thing
# Print out a quantity in a different unit:
print $d->ToString('mile');
print $d->convert('mile'), " mile\n"; # same thing
$d2 = new Physics::Unit::Distance('2000'); # no unit given, use the default
print $d2->ToString, "\n";
# Manipulate Times
$t = Physics::Unit::Time->new('36 years');
print $t->ToString, "\n"; # prints '1136073600 second'
# Speed equals Distance / Time
$s = $d->div($t); # $s is a Physics::Unit::Speed object
print $s->ToString, "\n"; # prints ''
# Create a Scalar with an unknown type
$s = new Physics::Unit::Scalar('kg m s');
$f = $s->div('3000 s^3'); # $f is a Physics::Unit::Force
DEBUG OPTION
Before the use statement, include a line turning debugging on, as in:
BEGIN { $Physics::Unit::Scalar::debug = 1; }
use Physics::Unit::Scalar;
This will cause copious debugging output to be generated. It will also cause the creation of a file, Scalar_subtypes.pm, which defines all of the subclasses of Scalar, based on the Unit types. The text of this file is evaled in order to define the subclasses.
Classes and objects derived from Physics::Unit::Scalar follow these rules:
* All objects of a particular class that derives from Physics::Unit::Scalar use the same Physics::Unit object, and thus have the same dimensionality and scale.
* Objects of the Physics::Unit::Scalar class (and not a derived class) each have their own Physics::Unit object to describe the quantity.
Thus, for example, all objects of type Physics::Unit::Distance use the Unit object "1 meter". Objects of type Physics::Unit::Acceleration use the Unit object "1 meter / sec^2".
Objects of type Physics::Unit::Scalar (and not a derived class) can use any Unit whatsoever, for example, "1 furlong". There could also exist an object of type Physics::Unit::Scalar using the Unit "1 meter", but that does not imply that it is a Physics::Unit::Distance object. The distinction is important when considering the methods that can be used to manipulate and combine different Scalar types.
PUBLIC METHODS
new()
Make a new user defined unit.
# This creates an object of a derived class
$d = new Physics::Unit::Distance('3 miles');
# This does the same thing, type is figured out automagically
$d = new Physics::Unit::Scalar('3 miles'); # $d is a Physics::Unit::Distance
# Use the default unit for the subtype (for Distance, it's meters):
$d = new Physics::Unit::Distance(10);
# This defaults to one meter:
$d = new Physics::Unit::Distance;
# Copy constructor:
$d2 = $d->new;
This method allows you to create new Scalar objects in a number of ways.
If the type cannot be identified by the dimensionality of the unit, then a Physics::Unit::Scalar object is returned. For example:
$s = new Physics::Unit::Scalar('kg m s');
ScalarFactory()
Creates a new object of one of the subtypes of Scalar, from a definition string (format is the same as that used by the Physics::Unit module).
The class of the resultant object is the same as the type of the unit created.
If the type is undef, then the class of the resultant object will be 'Physics::Unit::Scalar'.
If the type is 'unknown', then this function will throw an exception (die).
default_unit()
Get or set the default unit object which is used when printing out the given Scalar.
ToString()
$s = $scalar->ToString([unit]);
Prints out the scalar either in the default units or the unit specified.
convert()
$v = $scalar->convert(unit);
value()
Get or set the value.
add()
Add another Scalar to the provided one.
neg()
Take the negative of the Scalar
subtract()
Subtract another Scalar from this one
times()
This returns a new Scalar object which is the product of $self and the scalar argument: i.e.:
$newscalar = $self * $other
Neither the original object nor the argument is changed.
recip()
Returns a new Scalar object which is the reciprocal of the object.
The original object is unchanged.
div()
This returns a new Scalar object which is a quotient, i.e.
$newscalar = $self / $other
Neither the original object nor the argument is changed.
GetScalar()
This function is used by many of the arithmetic function methods, wherever an argument specifies a Scalar. Those arguments can be passed either as an actual Physics::Unit::Scalar object or as a string.
This function returns a blessed Physics::Unit::Scalar object.
PRIVATE METHODS
InitSubtypes()
This is called during compilation, and creates classes for each of the unit types defined in Physics::Unit.
If $debug is set, then it prints out the modules it creates to a file called ScalarSubtypes.pm.
MyUnit()
Returns a reference to the Unit object that is used to define the quantity.
GetMyUnit()
Get the class MyUnit.
GetDefaultUnit()
Get the class DefaultUnit.
ScalarResolve()
This takes an unblessed reference to a hash as an argument. The hash should have a value member and a MyUnit member.
This determines the proper type of Scalar that the object should be (based on MyUnit's type), 'normalizes' the Scalar, blesses it into the proper subtype, and returns it.
This is used by ScalarFactory and several of the arithmetic functions (whenever the arithmetic function actually changes the dimensionality of the unit, and thus the type of scalar).
AUTHOR
Chris Maloney <Dude@ChrisMaloney.com>
COPYRIGHT AND LICENSE
Copyright 2002-2003 by Chris Maloney
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.