The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Physics::Unit::Implementation - This page discusses implementation issues of the Physics/Unit.pm module.

Data Structures

%reserved_word

A list of reserved words in Unit expressions.

%unit_by_name

A list of all known unit names. The value of the hash is a reference to the named unit object.

%prefix

A list of all the valid prefixes. The value of the hash is a reference to the unit object. Note that the names here are also in %unit_by_name.

These are special case unit names that can be attached to other units with no intervening spaces.

%prototype

A list of all the known types. The values of this hash are references to unit objects that exemplify these types. I.e., any other units that have the same type will have the same dimensionality as the example unit.

$NumBases

The number of base units.

@BaseName

The name of each of the base units. These names also appear in %unit_by_name.

Initialization

InitBaseUnit is called to inform the library how many independent dimensional quantities there are, and what the 'base' unit is for each quantity. The library is initialized to know about nine quantities. More can be added at run-time, if desired.

InitPrefix is called to initialize the prefixes. Prefixes are just like dimensionless units, but they don't need to be separated from the next unit by a space. Prefix units can only have one name.

Next, InitUnit is called to define units in terms of other units. Note: no forward references are allowed here.

Private Implementation Routines

These are not part of the user-interface. These are only for use within the package.

NewOne()

Creates a new dimensionless unit.

AddNames()

This is called during the object's construction to add a list of names to the 'names' array, and to set the reference in the %unit_by_names cross-reference hash.

NewType()

   $u->NewType('type');

This is called when we are adding a new type to the system. This happens both in InitBaseUnits() and in InitTypes().

CreateUnit()

This is used by several of the interface utility functions to create a new unit object from a unit definition (either a simple name, a unit expression, or a unit object).

It differs from GetUnit in that it always creates a new, anonymous unit, whereas GetUnit, if given a simple name, returns a reference to a named unit.

CompareDim()

Compare the dimension arrays. Return 0 if they are the same.

LookName()

Look up the name. Returns:

  0 not defined
  1 reserved word
  2 unit name
  3 type name

DebugString()

Convert the unit to a factor - dimension vector format string, e.g. the unit '3 meters' would be converted to something like

  3 [1, 0, 0]

CheckChange()

Complain if this unit has a name. This is used by all the methods that modify the value of the unit.

The Parser

Below are listed the private parser functions. See also the grammar description in the Unit.pm documentation.

expr()

  expr : term
       | term '/' expr
       | term '*' expr
       | term 'per' expr

term()

  term : factor
       | term factor

A term is any number of factors separated (nominally) by whitespace. Whitespace is an 'operator' that means the same thing as multiplication, but has a higher priority than either '*', '/', or 'per'.

Examples of terms (the following lines each contain one term):

  3pi radians
  3e+4 globules

Factor()

  factor : prim
         | prim '**' integer

Note that a primary can be an integer, of course, so factors can look like this:

  meter ** 3 ^ 5    # note, '**' and '^' are synonymous

prim()

  prim : number
       | word
       | '(' expr ')'
       | 'square' primary
       | 'sq' primary
       | 'cubic' primary
       | primary 'squared'
       | primary 'cubed'

The unary operators square, sq, cubic, squared, and cubed are implemented as part of this function. Thus they have quite a high precedence, as I think they should.

get_token()

Only used by new above to parse the unit definition string.