Class: Unit
- Includes:
- Comparable
- Defined in:
- lib/ruby_units/ruby-units.rb,
lib/ruby_units/units.rb
Overview
Unit.setup
Constant Summary collapse
- UNIT_DEFINITIONS =
{ # prefixes '<googol>' => [%w{googol}, 1e100, :prefix], '<kibi>' => [%w{Ki Kibi kibi}, 2**10, :prefix], '<mebi>' => [%w{Mi Mebi mebi}, 2**20, :prefix], '<gibi>' => [%w{Gi Gibi gibi}, 2**30, :prefix], '<tebi>' => [%w{Ti Tebi tebi}, 2**40, :prefix], '<pebi>' => [%w{Pi Pebi pebi}, 2**50, :prefix], '<exi>' => [%w{Ei Exi exi}, 2**60, :prefix], '<zebi>' => [%w{Zi Zebi zebi}, 2**70, :prefix], '<yebi>' => [%w{Yi Yebi yebi}, 2**80, :prefix], '<yotta>' => [%w{Y Yotta yotta}, 1e24, :prefix], '<zetta>' => [%w{Z Zetta zetta}, 1e21, :prefix], '<exa>' => [%w{E Exa exa}, 1e18, :prefix], '<peta>' => [%w{P Peta peta}, 1e15, :prefix], '<tera>' => [%w{T Tera tera}, 1e12, :prefix], '<giga>' => [%w{G Giga giga}, 1e9, :prefix], '<mega>' => [%w{M Mega mega}, 1e6, :prefix], '<kilo>' => [%w{k kilo}, 1e3, :prefix], '<hecto>' => [%w{h Hecto hecto}, 1e2, :prefix], '<deca>' => [%w{da Deca deca deka}, 1e1, :prefix], '<deci>' => [%w{d Deci deci}, 1e-1, :prefix], '<centi>' => [%w{c Centi centi}, 1e-2, :prefix], '<milli>' => [%w{m Milli milli}, 1e-3, :prefix], '<micro>' => [%w{u Micro micro}, 1e-6, :prefix], '<nano>' => [%w{n Nano nano}, 1e-9, :prefix], '<pico>' => [%w{p Pico pico}, 1e-12, :prefix], '<femto>' => [%w{f Femto femto}, 1e-15, :prefix], '<atto>' => [%w{a Atto atto}, 1e-18, :prefix], '<zepto>' => [%w{z Zepto zepto}, 1e-21, :prefix], '<yocto>' => [%w{y Yocto yocto}, 1e-24, :prefix], '<1>' => [%w{1},1,:prefix], # length units '<meter>' => [%w{m meter meters metre metres}, 1.0, :length, %w{<meter>} ], '<inch>' => [%w{in inch inches "}, 0.0254, :length, %w{<meter>}], '<foot>' => [%w{ft foot feet '}, 0.3048, :length, %w{<meter>}], '<yard>' => [%w{yd yard yards}, 0.9144, :length, %w{<meter>}], '<mile>' => [%w{mi mile miles}, 1609.344, :length, %w{<meter>}], '<naut-mile>' => [%w{nmi}, 1852, :length, %w{<meter>}], '<league>'=> [%w{league leagues}, 4828, :length, %w{<meter>}], '<furlong>'=> [%w{furlong furlongs}, 201.2, :length, %w{<meter>}], '<rod>' => [%w{rd rod rods}, 5.029, :length, %w{<meter>}], '<mil>' => [%w{mil mils}, 0.0000254, :length, %w{<meter>}], '<angstrom>' =>[%w{ang angstrom angstroms}, 1e-10, :length, %w{<meter>}], '<fathom>' => [%w{fathom fathoms}, 1.829, :length, %w{<meter>}], '<pica>' => [%w{pica picas}, 0.004217, :length, %w{<meter>}], '<point>' => [%w{pt point points}, 0.0003514, :length, %w{<meter>}], '<redshift>' => [%w{z red-shift}, 1.302773e26, :length, %w{<meter>}], '<AU>' => [%w{AU astronomical-unit}, 149597900000, :length, %w{<meter>}], '<light-second>'=>[%w{ls light-second}, 299792500, :length, %w{<meter>}], '<light-minute>'=>[%w{lmin light-minute}, 17987550000, :length, %w{<meter>}], '<light-year>' => [%w{ly light-year}, 9460528000000000, :length, %w{<meter>}], '<parsec>' => [%w{pc parsec parsecs}, 30856780000000000, :length, %w{<meter>}], #mass '<kilogram>' => [%w{kg kilogram kilograms}, 1.0, :mass, %w{<kilogram>}], '<AMU>' => [%w{u AMU amu}, 6.0221415e26, :mass, %w{<kilogram>}], '<dalton>' => [%w{Da Dalton Daltons dalton daltons}, 6.0221415e26, :mass, %w{<kilogram>}], '<slug>' => [%w{slug slugs}, 14.5939029, :mass, %w{<kilogram>}], '<short-ton>' => [%w{tn ton}, 907.18474, :mass, %w{<kilogram>}], '<metric-ton>'=>[%w{tonne}, 1000, :mass, %w{<kilogram>}], '<carat>' => [%w{ct carat carats}, 0.0002, :mass, %w{<kilogram>}], '<pound>' => [%w{lbs lb pound pounds #}, 0.45359237, :mass, %w{<kilogram>}], '<ounce>' => [%w{oz ounce ounces}, 0.0283495231, :mass, %w{<kilogram>}], '<gram>' => [%w{g gram grams gramme grammes},1e-3,:mass, %w{<kilogram>}], #area '<hectare>'=>[%w{hectare}, 10000, :area, %w{<meter> <meter>}], '<acre>'=>[%w(acre acres), 4046.85642, :area, %w{<meter> <meter>}], '<sqft>'=>[%w(sqft), 1, :area, %w{<feet> <feet>}], #volume '<liter>' => [%w{l L liter liters litre litres}, 0.001, :volume, %w{<meter> <meter> <meter>}], '<barrel>' => [%w{bbl bbls barrel barrels}, 0.00852167911, :volume, %w{<meter> <meter> <meter>}], '<keg>' => [%w{keg kegs}, 0.0170433582, :volume, %w{<meter> <meter> <meter>}], '<gallon>'=> [%w{gal gallon gallons}, 0.0037854118, :volume, %w{<meter> <meter> <meter>}], '<quart>'=> [%w{qt quart quarts}, 0.00094635295, :volume, %w{<meter> <meter> <meter>}], '<pint>'=> [%w{pt pint pints}, 0.000473176475, :volume, %w{<meter> <meter> <meter>}], '<cup>'=> [%w{cu cup cups}, 0.000236588238, :volume, %w{<meter> <meter> <meter>}], '<fluid-ounce>'=> [%w{floz fluid-ounce}, 2.95735297e-5, :volume, %w{<meter> <meter> <meter>}], '<tablespoon>'=> [%w{tbs tablespoon tablespoons}, 1.47867648e-5, :volume, %w{<meter> <meter> <meter>}], '<teaspoon>'=> [%w{tsp teaspoon teaspoons}, 4.92892161e-6, :volume, %w{<meter> <meter> <meter>}], #speed '<kph>' => [%w{kph}, 0.277777778, :speed, %w{<meter>}, %w{<second>}], '<mph>' => [%w{mph}, 0.44704, :speed, %w{<meter>}, %w{<second>}], '<knot>' => [%w{kt kn kts knot knots}, 0.514444444, :speed, %w{<meter>}, %w{<second>}], '<fps>' => [%w{fps}, 0.3048, :speed, %w{<meter>}, %w{<second>}], #acceleration '<gee>' => [%w{gee}, 9.80655, :acceleration, %w{<meter>}, %w{<second> <second>}], #temperature_difference '<kelvin>' => [%w{degK kelvin}, 1.0, :temperature, %w{<kelvin>}], '<celsius>' => [%w{degC celsius celsius centigrade}, 1.0, :temperature, %w{<kelvin>}], '<fahrenheit>' => [%w{degF fahrenheit}, 1/1.8, :temperature, %w{<kelvin>}], '<rankine>' => [%w{degR rankine}, 1/1.8, :temperature, %w{<kelvin>}], '<temp-K>' => [%w{tempK}, 1.0, :temperature, %w{<temp-K>}], '<temp-C>' => [%w{tempC}, 1.0, :temperature, %w{<temp-K>}], '<temp-F>' => [%w{tempF}, 1/1.8, :temperature, %w{<temp-K>}], '<temp-R>' => [%w{tempR}, 1/1.8, :temperature, %w{<temp-K>}], #time '<second>'=> [%w{s sec second seconds}, 1.0, :time, %w{<second>}], '<minute>'=> [%w{min minute minutes}, 60.0, :time, %w{<second>}], '<hour>'=> [%w{h hr hrs hour hours}, 3600.0, :time, %w{<second>}], '<day>'=> [%w{d day days}, 3600*24, :time, %w{<second>}], '<week>'=> [%w{wk week weeks}, 7*3600*24, :time, %w{<second>}], '<fortnight>'=> [%w{fortnight fortnights}, 1209600, :time, %W{<second>}], '<year>'=> [%w{y yr year years annum}, 31556926, :time, %w{<second>}], '<decade>'=>[%w{decade decades}, 315569260, :time, %w{<second>}], '<century>'=>[%w{century centuries}, 3155692600, :time, %w{<second>}], #pressure '<pascal>' => [%w{Pa pascal Pascal}, 1.0, :pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<bar>' => [%w{bar bars}, 100000, :pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<mmHg>' => [%w{mmHg}, 133.322368,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<inHg>' => [%w{inHg}, 3386.3881472,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<torr>' => [%w{torr}, 133.322368,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<bar>' => [%w{bar}, 100000,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<atm>' => [%w{atm ATM atmosphere atmospheres}, 101325,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<psi>' => [%w{psi}, 6894.76,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<cmh2o>' => [%w{cmH2O}, 98.0638,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], '<inh2o>' => [%w{inH2O}, 249.082052,:pressure, %w{<kilogram>},%w{<meter> <second> <second>}], #viscosity '<poise>' => [%w{P poise}, 0.1, :viscosity, %w{<kilogram>},%w{<meter> <second>} ], '<stokes>' => [%w{St stokes}, 1e-4, :viscosity, %w{<meter> <meter>}, %w{<second>}], #substance '<mole>' => [%w{mol mole}, 1.0, :substance, %w{<mole>}], #concentration '<molar>' => [%w{M molar}, 1000, :concentration, %w{<mole>}, %w{<meter> <meter> <meter>}], '<wtpercent>' => [%w{wt% wtpercent}, 10, :concentration, %w{<kilogram>}, %w{<meter> <meter> <meter>}], #activity '<katal>' => [%w{kat katal Katal}, 1.0, :activity, %w{<mole>}, %w{<second>}], '<unit>' => [%w{U enzUnit}, 16.667e-16, :activity, %w{<mole>}, %w{<second>}], #capacitance '<farad>' => [%w{F farad Farad}, 1.0, :capacitance, %w{<farad>}], #charge '<coulomb>' => [%w{C coulomb Coulomb}, 1.0, :charge, %w{<ampere> <second>}], #current '<ampere>' => [%w{A Ampere ampere amp amps}, 1.0, :current, %w{<ampere>}], #conductance '<siemens>' => [%w{S Siemens siemens}, 1.0, :resistance, %w{<second> <second> <second> <ampere> <ampere>}, %w{<kilogram> <meter> <meter>}], #inductance '<henry>' => [%w{H Henry henry}, 1.0, :inductance, %w{<meter> <meter> <kilogram>}, %w{<second> <second> <ampere> <ampere>}], #potential '<volt>' => [%w{V Volt volt volts}, 1.0, :potential, %w{<meter> <meter> <kilogram>}, %w{<second> <second> <second> <ampere>}], #resistance '<ohm>' => [%w{Ohm ohm}, 1.0, :resistance, %w{<meter> <meter> <kilogram>},%w{<second> <second> <second> <ampere> <ampere>}], #magnetism '<weber>' => [%w{Wb weber webers}, 1.0, :magnetism, %w{<meter> <meter> <kilogram>}, %w{<second> <second> <ampere>}], '<tesla>' => [%w{T tesla teslas}, 1.0, :magnetism, %w{<kilogram>}, %w{<second> <second> <ampere>}], '<gauss>' => [%w{G gauss}, 1e-4, :magnetism, %w{<kilogram>}, %w{<second> <second> <ampere>}], '<maxwell>' => [%w{Mx maxwell maxwells}, 1e-8, :magnetism, %w{<meter> <meter> <kilogram>}, %w{<second> <second> <ampere>}], '<oersted>' => [%w{Oe oersted oersteds}, 250.0/Math::PI, :magnetism, %w{<ampere>}, %w{<meter>}], #energy '<joule>' => [%w{J joule Joule joules}, 1.0, :energy, %w{<meter> <meter> <kilogram>}, %w{<second> <second>}], '<erg>' => [%w{erg ergs}, 1e-7, :energy, %w{<meter> <meter> <kilogram>}, %w{<second> <second>}], '<btu>' => [%w{BTU btu BTUs}, 1055.056, :energy, %w{<meter> <meter> <kilogram>}, %w{<second> <second>}], '<calorie>' => [%w{cal calorie calories}, 4.18400, :energy,%w{<meter> <meter> <kilogram>}, %w{<second> <second>}], '<Calorie>' => [%w{Cal Calorie Calories}, 4184.00, :energy,%w{<meter> <meter> <kilogram>}, %w{<second> <second>}], '<therm-US>' => [%w{th therm therms Therm}, 105480400, :energy,%w{<meter> <meter> <kilogram>}, %w{<second> <second>}], #force '<newton>' => [%w{N Newton newton}, 1.0, :force, %w{<kilogram> <meter>}, %w{<second> <second>}], '<dyne>' => [%w{dyn dyne}, 1e-5, :force, %w{<kilogram> <meter>}, %w{<second> <second>}], '<pound-force>' => [%w{lbf pound-force}, 4.448222, :force, %w{<kilogram> <meter>}, %w{<second> <second>}], #frequency '<hertz>' => [%w{Hz hertz Hertz}, 1.0, :frequency, %w{<1>}, %{<second>}], #angle '<radian>' =>[%w{rad radian radian}, 1.0, :angle, %w{<radian>}], '<degree>' =>[%w{deg degree degrees}, Math::PI / 180.0, :angle, %w{<radian>}], '<grad>' =>[%w{grad gradian grads}, Math::PI / 200.0, :angle, %w{<radian>}], '<steradian>' => [%w{sr steradian steradians}, 1.0, :solid_angle, %w{<steradian>}], #rotation '<rotation>' => [%w{rotation}, 2.0*Math::PI, :angle, %w{<radian>}], '<rpm>' =>[%w{rpm}, 2.0*Math::PI / 60.0, :angular_velocity, %w{<radian>}, %w{<second>}], #memory '<byte>' =>[%w{B byte}, 1.0, :memory, %w{<byte>}], '<bit>' =>[%w{b bit}, 0.125, :memory, %w{<byte>}], #currency '<dollar>'=>[%w{USD dollar}, 1.0, :currency, %w{<dollar>}], '<cents>' =>[%w{cents}, 0.01, :currency, %w{<dollar>}], #luminosity '<candela>' => [%w{cd candela}, 1.0, :luminosity, %w{<candela>}], '<lumen>' => [%w{lm lumen}, 1.0, :luminous_power, %w{<candela> <steradian>}], '<lux>' =>[%w{lux}, 1.0, :illuminance, %w{<candela> <steradian>}, %w{<meter> <meter>}], #power '<watt>' => [%w{W watt watts}, 1.0, :power, %w{<kilogram> <meter> <meter>}, %w{<second> <second> <second>}], '<horsepower>' => [%w{hp horsepower}, 745.699872, :power, %w{<kilogram> <meter> <meter>}, %w{<second> <second> <second>}], #radiation '<gray>' => [%w{Gy gray grays}, 1.0, :radiation, %w{<meter> <meter>}, %w{<second> <second>}], '<roentgen>' => [%w{R roentgen}, 0.009330, :radiation, %w{<meter> <meter>}, %w{<second> <second>}], '<sievert>' => [%w{Sv sievert sieverts}, 1.0, :radiation, %w{<meter> <meter>}, %w{<second> <second>}], '<becquerel>' => [%w{Bq bequerel bequerels}, 1.0, :radiation, %w{<1>},%w{<second>}], '<curie>' => [%w{Ci curie curies}, 3.7e10, :radiation, %w{<1>},%w{<second>}], # rate '<cpm>' => [%w{cpm}, 1.0/60.0, :rate, %w{<count>},%w{<second>}], '<dpm>' => [%w{dpm}, 1.0/60.0, :rate, %w{<count>},%w{<second>}], '<bpm>' => [%w{bpm}, 1.0/60.0, :rate, %w{<count>},%w{<second>}], #resolution / typography '<dot>' => [%w{dot dots}, 1, :resolution, %w{<each>}], '<pixel>' => [%w{pixel px}, 1, :resolution, %w{<each>}], '<ppi>' => [%w{ppi}, 1, :resolution, %w{<pixel>}, %w{<inch>}], '<dpi>' => [%w{dpi}, 1, :typography, %w{<dot>}, %w{<inch>}], '<pica>' => [%w{pica}, 0.00423333333 , :typography, %w{<meter>}], '<point>' => [%w{point pt}, 0.000352777778, :typography, %w{<meter>}], #other '<cell>' => [%w{cells cell}, 1, :counting, %w{<each>}], '<each>' => [%w{each}, 1.0, :counting, %w{<each>}], '<count>' => [%w{count}, 1.0, :counting, %w{<each>}], '<base-pair>' => [%w{bp}, 1.0, :counting, %w{<each>}], '<nucleotide>' => [%w{nt}, 1.0, :counting, %w{<each>}], '<molecule>' => [%w{molecule molecules}, 1.0, :counting, %w{<1>}], '<dozen>' => [%w{doz dz dozen},12.0,:prefix_only, %w{<each>}], '<percent>'=> [%w{% percent}, 0.01, :prefix_only, %w{<1>}], '<ppm>' => [%w{ppm},1e-6,:prefix_only, %w{<1>}], '<ppt>' => [%w{ppt},1e-9,:prefix_only, %w{<1>}], '<gross>' => [%w{gr gross},144.0, :prefix_only, %w{<dozen> <dozen>}], '<decibel>' => [%w{dB decibel decibels}, 1.0, :logarithmic, %w{<decibel>}] }
- VERSION =
pre-generate hashes from unit definitions for performance.
'1.2.0.a'
- UNITY =
'<1>'
- UNITY_ARRAY =
[UNITY]
- FEET_INCH_REGEX =
/(\d+)\s*(?:'|ft|feet)\s*(\d+)\s*(?:"|in|inches)/
- TIME_REGEX =
/(\d+)*:(\d+)*:*(\d+)*[:,]*(\d+)*/
- LBS_OZ_REGEX =
/(\d+)\s*(?:#|lbs|pounds|pound-mass)+[\s,]*(\d+)\s*(?:oz|ounces)/
- SCI_NUMBER =
%r{([+-]?\d*[.]?\d+(?:[Ee][+-]?)?\d*)}
- RATIONAL_NUMBER =
/(\d+)\/(\d+)/
- COMPLEX_NUMBER =
/#{SCI_NUMBER}?#{SCI_NUMBER}i\b/
- NUMBER_REGEX =
/#{SCI_NUMBER}*\s*(.+)?/
- UNIT_STRING_REGEX =
/#{SCI_NUMBER}*\s*([^\/]*)\/*(.+)*/
- TOP_REGEX =
/([^ \*]+)(?:\^|\*\*)([\d-]+)/
- BOTTOM_REGEX =
/([^* ]+)(?:\^|\*\*)(\d+)/
- UNCERTAIN_REGEX =
/#{SCI_NUMBER}\s*\+\/-\s*#{SCI_NUMBER}\s(.+)/
- COMPLEX_REGEX =
/#{COMPLEX_NUMBER}\s?(.+)?/
- RATIONAL_REGEX =
/#{RATIONAL_NUMBER}\s?(.+)?/
- KELVIN =
['<kelvin>']
- FAHRENHEIT =
['<fahrenheit>']
- RANKINE =
['<rankine>']
- CELSIUS =
['<celsius>']
- SIGNATURE_VECTOR =
[:length, :time, :temperature, :mass, :current, :substance, :luminosity, :currency, :memory, :angle, :capacitance]
- @@USER_DEFINITIONS =
{}
- @@PREFIX_VALUES =
{}
- @@PREFIX_MAP =
{}
- @@UNIT_MAP =
{}
- @@UNIT_VALUES =
{}
- @@OUTPUT_MAP =
{}
- @@BASE_UNITS =
['<meter>','<kilogram>','<second>','<mole>', '<farad>', '<ampere>','<radian>','<kelvin>','<temp-K>','<byte>','<dollar>','<candela>','<each>','<steradian>','<decibel>']
- @@KINDS =
{ -312058=>:resistance, -312038=>:inductance, -152040=>:magnetism, -152038=>:magnetism, -152058=>:potential, -39=>:acceleration, -38=>:radiation, -20=>:frequency, -19=>:speed, -18=>:viscosity, 0=>:unitless, 1=>:length, 2=>:area, 3=>:volume, 20=>:time, 400=>:temperature, 7942=>:power, 7959=>:pressure, 7962=>:energy, 7979=>:viscosity, 7961=>:force, 7997=>:mass_concentration, 8000=>:mass, 159999=>:magnetism, 160000=>:current, 160020=>:charge, 312058=>:resistance, 3199980=>:activity, 3199997=>:molar_concentration, 3200000=>:substance, 63999998=>:illuminance, 64000000=>:luminous_power, 1280000000=>:currency, 25600000000=>:memory, 511999999980=>:angular_velocity, 512000000000=>:angle, 10240000000000=>:capacitance, }
- @@cached_units =
{}
- @@base_unit_cache =
{}
Instance Attribute Summary collapse
-
#base_denominator ⇒ Object
Returns the value of attribute base_denominator.
-
#base_numerator ⇒ Object
Returns the value of attribute base_numerator.
-
#base_scalar ⇒ Object
Returns the value of attribute base_scalar.
-
#denominator ⇒ Object
Returns the value of attribute denominator.
-
#numerator ⇒ Object
Returns the value of attribute numerator.
-
#output ⇒ Object
Returns the value of attribute output.
-
#scalar ⇒ Object
Returns the value of attribute scalar.
-
#signature ⇒ Object
Returns the value of attribute signature.
-
#unit_name ⇒ Object
Returns the value of attribute unit_name.
Class Method Summary collapse
- .base_unit_cache ⇒ Object
- .cached ⇒ Object
- .clear_cache ⇒ Object
- .parse(input) ⇒ Object
- .setup ⇒ Object
Instance Method Summary collapse
-
#*(other) ⇒ Object
Multiply two units.
-
#**(other) ⇒ Object
Exponentiate.
-
#+(other) ⇒ Object
Add two units together.
-
#-(other) ⇒ Object
Subtract two units.
-
#-@ ⇒ Object
negates the scalar of the Unit.
-
#/(other) ⇒ Object
Divide two units.
-
#<=>(other) ⇒ Object
Compare two Unit objects.
-
#===(other) ⇒ Object
(also: #same?, #same_as?)
Compare two units.
-
#=~(other) ⇒ Object
(also: #compatible?, #compatible_with?)
check to see if units are compatible, but not the scalar part this check is done by comparing signatures for performance reasons if passed a string, it will create a unit object with the string and then do the comparison this permits a syntax like: unit =~ “mm” if you want to do a regexp on the unit string do this …
-
#abs ⇒ Object
returns abs of scalar, without the units.
-
#ago ⇒ Object
‘5 min’.unit.ago.
-
#before(time_point = ::Time.now) ⇒ Object
(also: #before_now)
‘5 min’.before(time).
- #ceil ⇒ Object
-
#coerce(other) ⇒ Object
automatically coerce objects to units when possible if an object defines a ‘to_unit’ method, it will be coerced using that method.
- #copy(from) ⇒ Object
-
#divmod(other) ⇒ Object
divide two units and return quotient and remainder when both units are in the same units we just use divmod on the raw scalars otherwise we use the scalar of the base unit which will be a float.
- #floor ⇒ Object
-
#from(time_point = ::Time.now) ⇒ Object
(also: #after, #from_now)
‘5 min’.from(time).
-
#initialize(*options) ⇒ Unit
constructor
Create a new Unit object.
-
#inspect(option = nil) ⇒ Object
Normally pretty prints the unit, but if you really want to see the guts of it, pass ‘:dump’.
-
#inverse ⇒ Object
returns inverse of Unit (1/unit).
-
#is_base? ⇒ Boolean
Returns ‘true’ if the Unit is represented in base units.
-
#is_degree? ⇒ Boolean
(also: #degree?)
true if a degree unit or equivalent.
-
#is_temperature? ⇒ Boolean
(also: #temperature?)
true if unit is a ‘temperature’, false if a ‘degree’ or anything else.
- #kind ⇒ Object
-
#kind_of?(klass) ⇒ Boolean
needed to make complex units play nice – otherwise not detected as a complex_generic.
-
#power(n) ⇒ Object
returns the unit raised to the n-th power.
-
#root(n) ⇒ Object
Calculates the n-th root of a unit, where n = (1..9) if n < 0, returns 1/unit^(1/n).
- #round ⇒ Object
-
#since(time_point = ::Time.now) ⇒ Object
‘min’.since(time).
-
#succ ⇒ Object
returns next unit in a range.
-
#temperature_scale ⇒ Object
returns the ‘degree’ unit associated with a temperature unit ‘100 tempC’.unit.temperature_scale #=> ‘degC’.
-
#to(other) ⇒ Object
(also: #>>, #convert_to)
convert to a specified unit string or to the same units as another Unit.
-
#to_base ⇒ Object
convert to base SI units results of the conversion are cached so subsequent calls to this will be fast.
-
#to_c ⇒ Object
converts the unit back to a complex if it is unitless.
- #to_date ⇒ Object
-
#to_datetime ⇒ Object
convert a duration to a DateTime.
-
#to_f ⇒ Object
converts the unit back to a float if it is unitless.
-
#to_i ⇒ Object
(also: #to_int)
if unitless, returns an int, otherwise raises an error.
-
#to_s(target_units = nil) ⇒ Object
Generate human readable output.
-
#to_time ⇒ Object
(also: #time)
Tries to make a Time object from current unit.
- #to_unit ⇒ Object (also: #unit)
- #to_yaml(opts = {}) ⇒ Object
- #to_yaml_properties ⇒ Object
- #truncate ⇒ Object
-
#unitless? ⇒ Boolean
returns true if no associated units false, even if the units are “unitless” like ‘radians, each, etc’.
-
#units ⇒ Object
returns the ‘unit’ part of the Unit object without the scalar.
-
#until(time_point = ::Time.now) ⇒ Object
‘min’.until(time).
-
#zero? ⇒ Boolean
true if scalar is zero.
Constructor Details
#initialize(*options) ⇒ Unit
Create a new Unit object. Can be initialized using a string, or a hash Valid formats include:
"5.6 kg*m/s^2"
"5.6 kg*m*s^-2"
"5.6 kilogram*meter*second^-2"
"2.2 kPa"
"37 degC"
"1" -- creates a unitless constant with value 1
"GPa" -- creates a unit with scalar 1 with units 'GPa'
6'4" -- recognized as 6 feet + 4 inches
8 lbs 8 oz -- recognized as 8 lbs + 8 ounces
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/ruby_units/ruby-units.rb', line 190 def initialize(*) @scalar = nil @base_scalar = nil @unit_name = nil @signature = nil @output = {} if .size == 2 begin cached = @@cached_units[[1]] * [0] copy(cached) rescue initialize("#{[0]} #{([1].units rescue [1])}") end return end if .size == 3 [1] = [1].join if [1].kind_of?(Array) [2] = [2].join if [2].kind_of?(Array) begin cached = @@cached_units["#{[1]}/#{[2]}"] * [0] copy(cached) rescue initialize("#{[0]} #{[1]}/#{[2]}") end return end case [0] when Hash @scalar = [0][:scalar] || 1 @numerator = [0][:numerator] || UNITY_ARRAY @denominator = [0][:denominator] || UNITY_ARRAY @signature = [0][:signature] when Array initialize(*[0]) return when Numeric @scalar = [0] @numerator = @denominator = UNITY_ARRAY when Time @scalar = [0].to_f @numerator = ['<second>'] @denominator = UNITY_ARRAY when DateTime @scalar = [0].ajd @numerator = ['<day>'] @denominator = UNITY_ARRAY when "" raise ArgumentError, "No Unit Specified" when String parse([0]) else raise ArgumentError, "Invalid Unit Format" end self.update_base_scalar raise ArgumentError, "Temperature out of range" if self.is_temperature? && self.base_scalar < 0 unary_unit = self.units || "" opt_units = [0].scan(NUMBER_REGEX)[0][1] if String === [0] unless @@cached_units.keys.include?(opt_units) || (opt_units =~ /(temp|deg(C|K|R|F))|(pounds|lbs[ ,]\d+ ounces|oz)|('\d+")|(ft|feet[ ,]\d+ in|inch|inches)|%|(#{TIME_REGEX})|i\s?(.+)?|±|\+\/-/) @@cached_units[opt_units] = (self.scalar == 1 ? self : opt_units.unit) if opt_units && !opt_units.empty? end unless @@cached_units.keys.include?(unary_unit) || (unary_unit =~ /(temp|deg)(C|K|R|F)/) then @@cached_units[unary_unit] = (self.scalar == 1 ? self : unary_unit.unit) end [@scalar, @numerator, @denominator, @base_scalar, @signature, @is_base].each {|x| x.freeze} self end |
Instance Attribute Details
#base_denominator ⇒ Object
Returns the value of attribute base_denominator.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def base_denominator @base_denominator end |
#base_numerator ⇒ Object
Returns the value of attribute base_numerator.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def base_numerator @base_numerator end |
#base_scalar ⇒ Object
Returns the value of attribute base_scalar.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def base_scalar @base_scalar end |
#denominator ⇒ Object
Returns the value of attribute denominator.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def denominator @denominator end |
#numerator ⇒ Object
Returns the value of attribute numerator.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def numerator @numerator end |
#output ⇒ Object
Returns the value of attribute output.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def output @output end |
#scalar ⇒ Object
Returns the value of attribute scalar.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def scalar @scalar end |
#signature ⇒ Object
Returns the value of attribute signature.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def signature @signature end |
#unit_name ⇒ Object
Returns the value of attribute unit_name.
142 143 144 |
# File 'lib/ruby_units/ruby-units.rb', line 142 def unit_name @unit_name end |
Class Method Details
.base_unit_cache ⇒ Object
273 274 275 |
# File 'lib/ruby_units/ruby-units.rb', line 273 def self.base_unit_cache return @@base_unit_cache end |
.cached ⇒ Object
263 264 265 |
# File 'lib/ruby_units/ruby-units.rb', line 263 def self.cached return @@cached_units end |
.clear_cache ⇒ Object
267 268 269 270 271 |
# File 'lib/ruby_units/ruby-units.rb', line 267 def self.clear_cache @@cached_units = {} @@base_unit_cache = {} Unit.new(1) end |
.parse(input) ⇒ Object
277 278 279 280 |
# File 'lib/ruby_units/ruby-units.rb', line 277 def self.parse(input) first, second = input.scan(/(.+)\s(?:in|to|as)\s(.+)/i).first second.nil? ? first.unit : first.unit.to(second) end |
.setup ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ruby_units/ruby-units.rb', line 115 def self.setup @@ALL_UNIT_DEFINITIONS = UNIT_DEFINITIONS.merge!(@@USER_DEFINITIONS) for unit in (@@ALL_UNIT_DEFINITIONS) do key, value = unit if value[2] == :prefix then @@PREFIX_VALUES[key]=value[1] for name in value[0] do @@PREFIX_MAP[name]=key end else @@UNIT_VALUES[key]={} @@UNIT_VALUES[key][:scalar]=value[1] @@UNIT_VALUES[key][:numerator]=value[3] if value[3] @@UNIT_VALUES[key][:denominator]=value[4] if value[4] for name in value[0] do @@UNIT_MAP[name]=key end end @@OUTPUT_MAP[key]=value[0][0] end @@PREFIX_REGEX = @@PREFIX_MAP.keys.sort_by {|prefix| [prefix.length, prefix]}.reverse.join('|') @@UNIT_REGEX = @@UNIT_MAP.keys.sort_by {|unit_name| [unit_name.length, unit]}.reverse.join('|') @@UNIT_MATCH_REGEX = /(#{@@PREFIX_REGEX})*?(#{@@UNIT_REGEX})\b/ Unit.new(1) end |
Instance Method Details
#*(other) ⇒ Object
Multiply two units.
547 548 549 550 551 552 553 554 555 556 557 558 559 560 |
# File 'lib/ruby_units/ruby-units.rb', line 547 def *(other) case other when Unit raise ArgumentError, "Cannot multiply by temperatures" if [other,self].any? {|x| x.is_temperature?} opts = Unit.eliminate_terms(@scalar*other.scalar, @numerator + other.numerator ,@denominator + other.denominator) opts.merge!(:signature => @signature + other.signature) Unit.new(opts) when Numeric Unit.new(:scalar=>@scalar*other, :numerator=>@numerator, :denominator=>@denominator, :signature => @signature) else x,y = coerce(other) x * y end end |
#**(other) ⇒ Object
Exponentiate. Only takes integer powers. Note that anything raised to the power of 0 results in a Unit object with a scalar of 1, and no units. Throws an exception if exponent is not an integer. Ideally this routine should accept a float for the exponent It should then convert the float to a rational and raise the unit by the numerator and root it by the denominator but, sadly, floats can’t be converted to rationals.
For now, if a rational is passed in, it will be used, otherwise we are stuck with integers and certain floats < 1
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
# File 'lib/ruby_units/ruby-units.rb', line 601 def **(other) raise ArgumentError, "Cannot raise a temperature to a power" if self.is_temperature? if Numeric === other return Unit("1") if other.zero? return self if other == 1 return self.inverse if other == -1 end case other when Rational self.power(other.numerator).root(other.denominator) when Integer self.power(other) when Float return self**(other.to_i) if other == other.to_i valid = (1..9).map {|x| 1/x} raise ArgumentError, "Not a n-th root (1..9), use 1/n" unless valid.include? other.abs self.root((1/other).to_int) else raise ArgumentError, "Invalid Exponent" end end |
#+(other) ⇒ Object
Add two units together. Result is same units as receiver and scalar and base_scalar are updated appropriately throws an exception if the units are not compatible. It is possible to add Time objects to units of time
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/ruby_units/ruby-units.rb', line 488 def +(other) if Unit === other case when self.zero? other.dup when self =~ other raise ArgumentError, "Cannot add two temperatures" if ([self, other].all? {|x| x.is_temperature?}) if [self, other].any? {|x| x.is_temperature?} if self.is_temperature? Unit.new(:scalar => (self.scalar + other.to(self.temperature_scale).scalar), :numerator => @numerator, :denominator=>@denominator, :signature => @signature) else Unit.new(:scalar => (other.scalar + self.to(other.temperature_scale).scalar), :numerator => other.numerator, :denominator=>other.denominator, :signature => other.signature) end else @q ||= ((@@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar) rescue (self.units.unit.to_base.scalar)) Unit.new(:scalar=>(self.base_scalar + other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature => @signature) end else raise ArgumentError, "Incompatible Units ('#{self}' not compatible with '#{other}')" end elsif Time === other other + self else x,y = coerce(other) y + x end end |
#-(other) ⇒ Object
Subtract two units. Result is same units as receiver and scalar and base_scalar are updated appropriately throws an exception if the units are not compatible.
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 |
# File 'lib/ruby_units/ruby-units.rb', line 518 def -(other) if Unit === other case when self.zero? -other.dup when self =~ other case when [self, other].all? {|x| x.is_temperature?} Unit.new(:scalar => (self.base_scalar - other.base_scalar), :numerator => KELVIN, :denominator => UNITY_ARRAY, :signature => @signature).to(self.temperature_scale) when self.is_temperature? Unit.new(:scalar => (self.base_scalar - other.base_scalar), :numerator => ['<temp-K>'], :denominator => UNITY_ARRAY, :signature => @signature).to(self) when other.is_temperature? raise ArgumentError, "Cannot subtract a temperature from a differential degree unit" else @q ||= ((@@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar) rescue (self.units.unit.scalar/self.units.unit.to_base.scalar)) Unit.new(:scalar=>(self.base_scalar - other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature=>@signature) end else raise ArgumentError, "Incompatible Units ('#{self}' not compatible with '#{other}')" end elsif Time === other other - self else x,y = coerce(other) y-x end end |
#-@ ⇒ Object
negates the scalar of the Unit
796 797 798 799 |
# File 'lib/ruby_units/ruby-units.rb', line 796 def -@ return -@scalar if self.unitless? self.dup * -1 end |
#/(other) ⇒ Object
Divide two units. Throws an exception if divisor is 0
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 |
# File 'lib/ruby_units/ruby-units.rb', line 564 def /(other) case other when Unit raise ZeroDivisionError if other.zero? raise ArgumentError, "Cannot divide with temperatures" if [other,self].any? {|x| x.is_temperature?} opts = Unit.eliminate_terms(@scalar/other.scalar, @numerator + other.denominator ,@denominator + other.numerator) opts.merge!(:signature=> @signature - other.signature) Unit.new(opts) when Numeric raise ZeroDivisionError if other.zero? Unit.new(:scalar=>@scalar/other, :numerator=>@numerator, :denominator=>@denominator, :signature => @signature) else x,y = coerce(other) y / x end end |
#<=>(other) ⇒ Object
Compare two Unit objects. Throws an exception if they are not of compatible types. Comparisons are done based on the value of the unit in base SI units.
434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/ruby_units/ruby-units.rb', line 434 def <=>(other) case when other.zero? && !self.is_temperature? return self.base_scalar <=> 0 when Unit === other raise ArgumentError, "Incompatible Units" unless self =~ other return self.base_scalar <=> other.base_scalar else x,y = coerce(other) return x <=> y end end |
#===(other) ⇒ Object Also known as: same?, same_as?
Compare two units. Returns true if quantities and units match
Unit(“100 cm”) === Unit(“100 cm”) # => true Unit(“100 cm”) === Unit(“1 m”) # => false
472 473 474 475 476 477 478 479 480 |
# File 'lib/ruby_units/ruby-units.rb', line 472 def ===(other) case other when Unit (self.scalar == other.scalar) && (self.units == other.units) else x,y = coerce(other) x === y end end |
#=~(other) ⇒ Object Also known as: compatible?, compatible_with?
check to see if units are compatible, but not the scalar part this check is done by comparing signatures for performance reasons if passed a string, it will create a unit object with the string and then do the comparison this permits a syntax like:
unit =~ "mm"
if you want to do a regexp on the unit string do this …
unit.units =~ /regexp/
454 455 456 457 458 459 460 461 462 463 |
# File 'lib/ruby_units/ruby-units.rb', line 454 def =~(other) return true if self == 0 || other == 0 case other when Unit self.signature == other.signature else x,y = coerce(other) x =~ y end end |
#abs ⇒ Object
returns abs of scalar, without the units
802 803 804 |
# File 'lib/ruby_units/ruby-units.rb', line 802 def abs return @scalar.abs end |
#ago ⇒ Object
‘5 min’.unit.ago
855 856 857 |
# File 'lib/ruby_units/ruby-units.rb', line 855 def ago self.before end |
#before(time_point = ::Time.now) ⇒ Object Also known as: before_now
‘5 min’.before(time)
860 861 862 863 864 865 866 867 |
# File 'lib/ruby_units/ruby-units.rb', line 860 def before(time_point = ::Time.now) raise ArgumentError, "Must specify a Time" unless time_point if String === time_point time_point.time - self rescue time_point.datetime - self else time_point - self rescue time_point.to_datetime - self end end |
#ceil ⇒ Object
806 807 808 809 |
# File 'lib/ruby_units/ruby-units.rb', line 806 def ceil return @scalar.ceil if self.unitless? Unit.new(@scalar.ceil, @numerator, @denominator) end |
#coerce(other) ⇒ Object
automatically coerce objects to units when possible if an object defines a ‘to_unit’ method, it will be coerced using that method
920 921 922 923 924 925 926 927 928 929 930 |
# File 'lib/ruby_units/ruby-units.rb', line 920 def coerce(other) if other.respond_to? :to_unit return [other.to_unit, self] end case other when Unit [other, self] else [Unit.new(other), self] end end |
#copy(from) ⇒ Object
154 155 156 157 158 159 160 161 162 |
# File 'lib/ruby_units/ruby-units.rb', line 154 def copy(from) @scalar = from.scalar @numerator = from.numerator @denominator = from.denominator @is_base = from.is_base? @signature = from.signature @base_scalar = from.base_scalar @unit_name = from.unit_name rescue nil end |
#divmod(other) ⇒ Object
divide two units and return quotient and remainder when both units are in the same units we just use divmod on the raw scalars otherwise we use the scalar of the base unit which will be a float
584 585 586 587 588 589 590 591 |
# File 'lib/ruby_units/ruby-units.rb', line 584 def divmod(other) raise ArgumentError, "Incompatible Units" unless self =~ other if self.units == other.units return self.scalar.divmod(other.scalar) else return self.to_base.scalar.divmod(other.to_base.scalar) end end |
#floor ⇒ Object
811 812 813 814 |
# File 'lib/ruby_units/ruby-units.rb', line 811 def floor return @scalar.floor if self.unitless? Unit.new(@scalar.floor, @numerator, @denominator) end |
#from(time_point = ::Time.now) ⇒ Object Also known as: after, from_now
‘5 min’.from(time)
899 900 901 902 903 904 905 906 |
# File 'lib/ruby_units/ruby-units.rb', line 899 def from(time_point = ::Time.now) raise ArgumentError, "Must specify a Time" unless time_point if String === time_point time_point.time + self rescue time_point.datetime + self else time_point + self rescue time_point.to_datetime + self end end |
#inspect(option = nil) ⇒ Object
Normally pretty prints the unit, but if you really want to see the guts of it, pass ‘:dump’
401 402 403 404 |
# File 'lib/ruby_units/ruby-units.rb', line 401 def inspect(option=nil) return super() if option == :dump self.to_s end |
#inverse ⇒ Object
returns inverse of Unit (1/unit)
668 669 670 |
# File 'lib/ruby_units/ruby-units.rb', line 668 def inverse Unit("1") / self end |
#is_base? ⇒ Boolean
Returns ‘true’ if the Unit is represented in base units
288 289 290 291 292 293 294 295 296 |
# File 'lib/ruby_units/ruby-units.rb', line 288 def is_base? return @is_base if defined? @is_base return @is_base=true if self.degree? && self.numerator.size == 1 && self.denominator == UNITY_ARRAY && self.units =~ /(deg|temp)K/ n = @numerator + @denominator for x in n.compact do return @is_base=false unless x == UNITY || (@@BASE_UNITS.include?((x))) end return @is_base = true end |
#is_degree? ⇒ Boolean Also known as: degree?
true if a degree unit or equivalent.
413 414 415 |
# File 'lib/ruby_units/ruby-units.rb', line 413 def is_degree? self.kind == :temperature end |
#is_temperature? ⇒ Boolean Also known as: temperature?
true if unit is a ‘temperature’, false if a ‘degree’ or anything else
407 408 409 |
# File 'lib/ruby_units/ruby-units.rb', line 407 def is_temperature? self.is_degree? && self.units =~ /temp/ end |
#kind ⇒ Object
259 260 261 |
# File 'lib/ruby_units/ruby-units.rb', line 259 def kind return @@KINDS[self.signature] end |
#kind_of?(klass) ⇒ Boolean
needed to make complex units play nice – otherwise not detected as a complex_generic
150 151 152 |
# File 'lib/ruby_units/ruby-units.rb', line 150 def kind_of?(klass) self.scalar.kind_of?(klass) end |
#power(n) ⇒ Object
returns the unit raised to the n-th power. Integers only
624 625 626 627 628 629 630 631 632 633 634 635 |
# File 'lib/ruby_units/ruby-units.rb', line 624 def power(n) raise ArgumentError, "Cannot raise a temperature to a power" if self.is_temperature? raise ArgumentError, "Can only use Integer exponenents" unless Integer === n return self if n == 1 return Unit("1") if n == 0 return self.inverse if n == -1 if n > 0 then (1..(n-1).to_i).inject(self) {|product, x| product * self} else (1..-(n-1).to_i).inject(self) {|product, x| product / self} end end |
#root(n) ⇒ Object
Calculates the n-th root of a unit, where n = (1..9) if n < 0, returns 1/unit^(1/n)
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 |
# File 'lib/ruby_units/ruby-units.rb', line 639 def root(n) raise ArgumentError, "Cannot take the root of a temperature" if self.is_temperature? raise ArgumentError, "Exponent must an Integer" unless Integer === n raise ArgumentError, "0th root undefined" if n == 0 return self if n == 1 return self.root(n.abs).inverse if n < 0 vec = self.unit_signature_vector vec=vec.map {|x| x % n} raise ArgumentError, "Illegal root" unless vec.max == 0 num = @numerator.dup den = @denominator.dup for item in @numerator.uniq do x = num.find_all {|i| i==item}.size r = ((x/n)*(n-1)).to_int r.times {|y| num.delete_at(num.index(item))} end for item in @denominator.uniq do x = den.find_all {|i| i==item}.size r = ((x/n)*(n-1)).to_int r.times {|y| den.delete_at(den.index(item))} end q = @scalar < 0 ? (-1)**Rational(1,n) * (@scalar.abs)**Rational(1,n) : @scalar**Rational(1,n) Unit.new(:scalar=>q,:numerator=>num,:denominator=>den) end |
#round ⇒ Object
844 845 846 847 |
# File 'lib/ruby_units/ruby-units.rb', line 844 def round return @scalar.round if self.unitless? Unit.new(@scalar.round, @numerator, @denominator) end |
#since(time_point = ::Time.now) ⇒ Object
‘min’.since(time)
871 872 873 874 875 876 877 878 879 880 881 882 |
# File 'lib/ruby_units/ruby-units.rb', line 871 def since(time_point = ::Time.now) case time_point when Time (Time.now - time_point).unit('s').to(self) when DateTime, Date (DateTime.now - time_point).unit('d').to(self) when String (DateTime.now - time_point.to_datetime(:context=>:past)).unit('d').to(self) else raise ArgumentError, "Must specify a Time, DateTime, or String" end end |
#succ ⇒ Object
returns next unit in a range. ‘1 mm’.unit.succ #=> ‘2 mm’.unit only works when the scalar is an integer
912 913 914 915 916 |
# File 'lib/ruby_units/ruby-units.rb', line 912 def succ raise ArgumentError, "Non Integer Scalar" unless @scalar == @scalar.to_i q = @scalar.to_i.succ Unit.new(q, @numerator, @denominator) end |
#temperature_scale ⇒ Object
returns the ‘degree’ unit associated with a temperature unit ‘100 tempC’.unit.temperature_scale #=> ‘degC’
420 421 422 423 424 |
# File 'lib/ruby_units/ruby-units.rb', line 420 def temperature_scale return nil unless self.is_temperature? self.units =~ /temp(C|F|R|K)/ "deg#{$1}" end |
#to(other) ⇒ Object Also known as: >>, convert_to
convert to a specified unit string or to the same units as another Unit
unit >> "kg" will covert to kilograms
unit1 >> unit2 converts to same units as unit2 object
To convert a Unit object to match another Unit object, use:
unit1 >>= unit2
Throws an exception if the requested target units are incompatible with current Unit.
Special handling for temperature conversions is supported. If the Unit object is converted from one temperature unit to another, the proper temperature offsets will be used. Supports Kelvin, Celsius, fahrenheit, and Rankine scales.
Note that if temperature is part of a compound unit, the temperature will be treated as a differential and the units will be scaled appropriately.
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 |
# File 'lib/ruby_units/ruby-units.rb', line 687 def to(other) return self if other.nil? return self if TrueClass === other return self if FalseClass === other if (Unit === other && other.is_temperature?) || (String === other && other =~ /temp(K|C|R|F)/) raise ArgumentError, "Receiver is not a temperature unit" unless self.degree? start_unit = self.units target_unit = other.units rescue other unless @base_scalar @base_scalar = case start_unit when 'tempC' @scalar + 273.15 when 'tempK' @scalar when 'tempF' (@scalar+459.67)*(5.0/9.0) when 'tempR' @scalar*(5.0/9.0) end end q= case target_unit when 'tempC' @base_scalar - 273.15 when 'tempK' @base_scalar when 'tempF' @base_scalar * (9.0/5.0) - 459.67 when 'tempR' @base_scalar * (9.0/5.0) end Unit.new("#{q} #{target_unit}") else case other when Unit return self if other.units == self.units target = other when String target = Unit.new(other) else raise ArgumentError, "Unknown target units" end raise ArgumentError, "Incompatible Units" unless self =~ target one = @numerator.map {|x| @@PREFIX_VALUES[x] ? @@PREFIX_VALUES[x] : x}.map {|i| i.kind_of?(Numeric) ? i : @@UNIT_VALUES[i][:scalar] }.compact two = @denominator.map {|x| @@PREFIX_VALUES[x] ? @@PREFIX_VALUES[x] : x}.map {|i| i.kind_of?(Numeric) ? i : @@UNIT_VALUES[i][:scalar] }.compact v = one.inject(1) {|product,n| product*n} / two.inject(1) {|product,n| product*n} one = target.numerator.map {|x| @@PREFIX_VALUES[x] ? @@PREFIX_VALUES[x] : x}.map {|x| x.kind_of?(Numeric) ? x : @@UNIT_VALUES[x][:scalar] }.compact two = target.denominator.map {|x| @@PREFIX_VALUES[x] ? @@PREFIX_VALUES[x] : x}.map {|x| x.kind_of?(Numeric) ? x : @@UNIT_VALUES[x][:scalar] }.compact y = one.inject(1) {|product,n| product*n} / two.inject(1) {|product,n| product*n} q = @scalar * v/y Unit.new(:scalar=>q, :numerator=>target.numerator, :denominator=>target.denominator, :signature => target.signature) end end |
#to_base ⇒ Object
convert to base SI units results of the conversion are cached so subsequent calls to this will be fast
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/ruby_units/ruby-units.rb', line 300 def to_base return self if self.is_base? if self.units =~ /\A(deg|temp)(C|F|K|C)\Z/ @signature = 400 base = case self.units when /temp/ self.to('tempK') when /deg/ self.to('degK') end return base end cached = ((@@base_unit_cache[self.units] * self.scalar) rescue nil) return cached if cached num = [] den = [] q = 1 for unit in @numerator.compact do if @@PREFIX_VALUES[unit] q *= @@PREFIX_VALUES[unit] else q *= @@UNIT_VALUES[unit][:scalar] if @@UNIT_VALUES[unit] num << @@UNIT_VALUES[unit][:numerator] if @@UNIT_VALUES[unit] && @@UNIT_VALUES[unit][:numerator] den << @@UNIT_VALUES[unit][:denominator] if @@UNIT_VALUES[unit] && @@UNIT_VALUES[unit][:denominator] end end for unit in @denominator.compact do if @@PREFIX_VALUES[unit] q /= @@PREFIX_VALUES[unit] else q /= @@UNIT_VALUES[unit][:scalar] if @@UNIT_VALUES[unit] den << @@UNIT_VALUES[unit][:numerator] if @@UNIT_VALUES[unit] && @@UNIT_VALUES[unit][:numerator] num << @@UNIT_VALUES[unit][:denominator] if @@UNIT_VALUES[unit] && @@UNIT_VALUES[unit][:denominator] end end num = num.flatten.compact den = den.flatten.compact num = UNITY_ARRAY if num.empty? base= Unit.new(Unit.eliminate_terms(q,num,den)) @@base_unit_cache[self.units]=base return base * @scalar end |
#to_c ⇒ Object
converts the unit back to a complex if it is unitless. Otherwise raises an exception
751 752 753 754 |
# File 'lib/ruby_units/ruby-units.rb', line 751 def to_c return Complex(@scalar) if self.unitless? raise RuntimeError, "Can't convert to Complex unless unitless. Use Unit#scalar" end |
#to_date ⇒ Object
840 841 842 |
# File 'lib/ruby_units/ruby-units.rb', line 840 def to_date Date.new0(self.to('d').scalar) end |
#to_datetime ⇒ Object
convert a duration to a DateTime. This will work so long as the duration is the duration from the zero date defined by DateTime
836 837 838 |
# File 'lib/ruby_units/ruby-units.rb', line 836 def to_datetime DateTime.new!(self.to('d').scalar) end |
#to_f ⇒ Object
converts the unit back to a float if it is unitless. Otherwise raises an exception
744 745 746 747 |
# File 'lib/ruby_units/ruby-units.rb', line 744 def to_f return @scalar.to_f if self.unitless? raise RuntimeError, "Can't convert to Float unless unitless (#{self.to_s}). Use Unit#scalar" end |
#to_i ⇒ Object Also known as: to_int
if unitless, returns an int, otherwise raises an error
817 818 819 820 |
# File 'lib/ruby_units/ruby-units.rb', line 817 def to_i return @scalar.to_int if self.unitless? raise RuntimeError, 'Cannot convert to Integer unless unitless' end |
#to_s(target_units = nil) ⇒ Object
Generate human readable output. If the name of a unit is passed, the unit will first be converted to the target unit before output. some named conversions are available
:ft - outputs in feet and inches (e.g., 6'4")
:lbs - outputs in pounds and ounces (e.g, 8 lbs, 8 oz)
You can also pass a standard format string (i.e., ‘%0.2f’) or a strftime format string.
output is cached so subsequent calls for the same format will be fast
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/ruby_units/ruby-units.rb', line 358 def to_s(target_units=nil) out = @output[target_units] if out return out else case target_units when :ft inches = self.to("in").scalar.to_int out = "#{(inches / 12).truncate}\'#{(inches % 12).round}\"" when :lbs ounces = self.to("oz").scalar.to_int out = "#{(ounces / 16).truncate} lbs, #{(ounces % 16).round} oz" when String out = case target_units when /(%[\-+\.\w#]+)\s*(.+)*/ #format string like '%0.2f in' begin if $2 #unit specified, need to convert self.to($2).to_s($1) else "#{$1 % @scalar} #{$2 || self.units}".strip end rescue (DateTime.new(0) + self).strftime(target_units) end when /(\S+)/ #unit only 'mm' or '1/mm' "#{self.to($1).to_s}" else raise "unhandled case" end else out = case @scalar when Rational "#{@scalar} #{self.units}" else "#{'%g' % @scalar} #{self.units}" end.strip end @output[target_units] = out return out end end |
#to_time ⇒ Object Also known as: time
Tries to make a Time object from current unit. Assumes the current unit hold the duration in seconds from the epoch.
824 825 826 |
# File 'lib/ruby_units/ruby-units.rb', line 824 def to_time Time.at(self) end |
#to_unit ⇒ Object Also known as: unit
282 283 284 |
# File 'lib/ruby_units/ruby-units.rb', line 282 def to_unit self end |
#to_yaml(opts = {}) ⇒ Object
167 168 169 170 171 172 173 174 175 |
# File 'lib/ruby_units/ruby-units.rb', line 167 def to_yaml( opts = {} ) YAML::quick_emit( object_id, opts ) do |out| out.map( taguri, to_yaml_style ) do |map| for m in to_yaml_properties do map.add( m[1..-1], instance_variable_get( m ) ) end end end end |
#to_yaml_properties ⇒ Object
144 145 146 |
# File 'lib/ruby_units/ruby-units.rb', line 144 def to_yaml_properties %w{@scalar @numerator @denominator @signature @base_scalar} end |
#truncate ⇒ Object
829 830 831 832 |
# File 'lib/ruby_units/ruby-units.rb', line 829 def truncate return @scalar.truncate if self.unitless? Unit.new(@scalar.truncate, @numerator, @denominator) end |
#unitless? ⇒ Boolean
returns true if no associated units false, even if the units are “unitless” like ‘radians, each, etc’
428 429 430 |
# File 'lib/ruby_units/ruby-units.rb', line 428 def unitless? (@numerator == UNITY_ARRAY && @denominator == UNITY_ARRAY) end |
#units ⇒ Object
returns the ‘unit’ part of the Unit object without the scalar
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 |
# File 'lib/ruby_units/ruby-units.rb', line 757 def units return "" if @numerator == UNITY_ARRAY && @denominator == UNITY_ARRAY return @unit_name unless @unit_name.nil? output_n = [] output_d =[] num = @numerator.clone.compact den = @denominator.clone.compact if @numerator == UNITY_ARRAY output_n << "1" else num.each_with_index do |token,index| if token && @@PREFIX_VALUES[token] then output_n << "#{@@OUTPUT_MAP[token]}#{@@OUTPUT_MAP[num[index+1]]}" num[index+1]=nil else output_n << "#{@@OUTPUT_MAP[token]}" if token end end end if @denominator == UNITY_ARRAY output_d = ['1'] else den.each_with_index do |token,index| if token && @@PREFIX_VALUES[token] then output_d << "#{@@OUTPUT_MAP[token]}#{@@OUTPUT_MAP[den[index+1]]}" den[index+1]=nil else output_d << "#{@@OUTPUT_MAP[token]}" if token end end end on = output_n.reject {|x| x.empty?}.map {|x| [x, output_n.find_all {|z| z==x}.size]}.uniq.map {|x| ("#{x[0]}".strip+ (x[1] > 1 ? "^#{x[1]}" : ''))} od = output_d.reject {|x| x.empty?}.map {|x| [x, output_d.find_all {|z| z==x}.size]}.uniq.map {|x| ("#{x[0]}".strip+ (x[1] > 1 ? "^#{x[1]}" : ''))} out = "#{on.join('*')}#{od == ['1'] ? '': '/'+od.join('*')}".strip @unit_name = out unless self.kind == :temperature return out end |
#until(time_point = ::Time.now) ⇒ Object
‘min’.until(time)
885 886 887 888 889 890 891 892 893 894 895 896 |
# File 'lib/ruby_units/ruby-units.rb', line 885 def until(time_point = ::Time.now) case time_point when Time (time_point - Time.now).unit('s').to(self) when DateTime, Date (time_point - DateTime.now).unit('d').to(self) when String (time_point.to_datetime(:context=>:future) - DateTime.now).unit('d').to(self) else raise ArgumentError, "Must specify a Time, DateTime, or String" end end |
#zero? ⇒ Boolean
true if scalar is zero
850 851 852 |
# File 'lib/ruby_units/ruby-units.rb', line 850 def zero? return self.to_base.scalar.zero? end |