NAME

Convert::Pluggable - convert between various units of measurement

VERSION

Version 0.031

SYNOPSIS

convert between various units of measurement

IMPORTANT NOTICE - FUNCTIONALITY ADDITION

You my use this module standalone prior to v0.031; there the units are all hard-coded into the module:

use Convert::Pluggable;

my $c = new Convert::Pluggable();

my $result = $c-convert( { 'factor' => '5', 'from_unit' => 'feet', 'to_unit' => 'inches', 'precision' => '3', } );>

Starting in v0.031 you may still use this module stand-alone, but you may optionally provide as a constructor argument the name of a data file (currently only supports JSON) - then you will be able to use C::P as a service. See examples/service.pl for an example Dancer2 script. See data/units.json for an example of a valid json data set.

See t/Convert-Pluggable.t for many more example uses.

See https://ddh5.duckduckgo.com/?q=10000+minutes+in+microseconds for examples of test uses

EXPORT

convert

SUBROUTINES/METHODS

new()

Create a new Conversion object.

new('/path/to/some/data.json')

Create a new Conversion object pre-loaded with serializable data to be used as a service.

convert_temperatures()

A function for converting between various temperature units. Currently supports Fahrenheit, Celsius, Kelvin, Rankine, and Raumur.

convert()

This is the workhorse. All conversion work (except for temperatures) gets done here. This is an exported sub.

get_matches()

  • get factors for later calculating conversion

  • get trigger 'types' to determine if we can perform a calculation in the first place

  • get canoncial units for massaging output

  • determine if a unit may be negative

    This gets some useful metadata for convert() to carry out its work.

get_units()

In versions prior to 0.031, this is where you add new unit types so that convert() can operate on them. This behavior is still supported. This is an exported sub.

Currently supported units of measurement are: mass, length, time, pressure, energy, power, angle, force, temperature, digital.

old_get_units()

If you don't pass in a data file on construction, units are gotten from a hardcoded hash in this source file.

parse_number()

handle numbers with special characters in them, like '6^2' and '2e3'. written by mwmiller.

AUTHOR

bradley andersen, <bradley at pvnp.us>

POSSIBLE BUGS (RE-INVESTIGATION NEEDED)

  • add back in guard against things like: '10 inches to 5 cm'

SUPPORT

You can find documentation for this module with the perldoc command.

You can also look for information at:

ACKNOWLEDGEMENTS

Special thanks to @mintsoft and @jagtalon

LICENSE AND COPYRIGHT

Copyright (c) 2014-2016 Bradley Andersen. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

PRIOR ART

Bot::BasicBot::Pluggable::Module::Convert

relies on

Math::Units

TODO

  • better error handling

  • all args to functions should be hash refs!

  • add more unit types (digital, cooking, etc.)

  • add roman numeral converter

  • add main units to aliases (easier for searching with things like redis)

  • support native perl numbers in queries: e.g.: '12.34e-56 cm to mm'

  • don't show decimals when integer answer? e.g.: '12.000' should be '12' (this may be something we leave to implementation ... see 'precision' argument)

  • add more tests and better test output

    • '1 year to months'

    • '16 years to months'

    • '12.34e-56 cm to mm'

    • '10 inches to 5 cm' should not try

  • what happens when two units have the same notation? (e.g., 'kilometer' and 'kilobyte' both can use 'K')

  • does convert work when ($from eq $to) ?

  • return undef when we find a unit/alias in more than one type ^ what if it's ok? e.g., "oz" can be a unit of both "mass" and "volume"

  • perl critic?

  • https://github.com/duckduckgo/zeroclickinfo-goodies/issues/1767

  • while massaging output is left to the implementation, there are some cases where answers might seem nonsensical, based on the input precision. for example, converting '10mg to tons' with a precision of '3' gives '10 milligrams is 0.000 tons' the code below is one way to handle such cases:

    if ($result == 0 || length($result) > 2*$precision + 1) {
        # '10 mg to tons'                 => [0] , [1.10231e-08]
        # '10000 minutes in microseconds' => [600000000000]
        # '2500kcal in tons of tnt'       => [66194.888]
    
        if ($result == 0) {
            # rounding error
            $result = convert_temperatures($matches->{'from_unit'}, $matches->{'to_unit'}, $factor);
        }
    
        $f_result = (sprintf "%.${precision}g", $result);
    }