Libraries for converting physical units (kilograms, pounds) in Ruby?
-
26-09-2019 - |
Question
I know Rails has some nice helpers for date and time management. Is there an already-working project consisting of, or incorporating a clean DSL for standard units and their conversions? Any project with helpers for the conversion between the two systems' basic units of length and weight would work. Thank you!
Solution
Wow, there are quite a few more of these than I expected. Here is what I believe to be a complete list, in alphabetical order, with example usage stripped from their documentation. I also noted if I couldn't get them running locally.
-
require 'alchemist' Alchemist.setup 8.miles.to.meters 10.kilometers + 1.mile # 11.609344 kilometers
-
This one appears out of date, the last commit was 5 years ago, and it doesn't seem to run on 1.9.3 for me.
include Measurement::Length Inch.new(12).to_centimeters # => #<Measurement::Length::Centimeter:0x173c2b4 @units=30.48>
-
require "phys/units" Q = Phys::Quantity U = Phys::Unit Q[1.23,'km'] + Q[4.56,'m'] #=> Phys::Quantity[1.23456,'km'] Q[123,'mile'] / Q[2,'hr'] #=> Phys::Quantity[61,'mile/hr'] Q[61,'miles/hr'].want('m/s') #=> Phys::Quantity[27.26944,'m/s'] Q[1.0,'are'] == Q[10,'m']**2 #=> true
-
Note that this one states that it is not production ready in the README.
require 'quantity/all' 1.meter #=> 1 meter 1.meter.to_feet #=> 3.28083... foot c = 299792458.meters / 1.second #=> 299792458 meter/second newton = 1.meter * 1.kilogram / 1.second**2 #=> 1 meter*kilogram/second^2 newton.to_feet #=> 3.28083989501312 foot*kilogram/second^2 newton.convert(:feet) #=> 3.28083989501312 foot*kilogram/second^2 jerk_newton = newton / 1.second #=> 1 meter*kilogram/second^3 jerk_newton * 1.second == newton #=> true
-
require 'ruby-measurement' measurement = Measurement.parse('3 feet') # => 3.0 ft. measurement.convert_to(:yards) # => 1.0 yd. measurement.convert_to(:in) # => 36.0 in. measurement.convert_to(:inches) # => 36.0 in. measurement1 = Measurement.parse('3 feet') # => 3.0 ft. measurement2 = Measurement.parse('6 inch') # => 6.0 in. measurement1 + measurement2 # => 3.5 ft.
-
require 'ruby-units' unit = Unit("mm") # unit only (defaults to a scalar of 1) unit = Unit("1 mm") # create a simple unit unit = Unit("1 kg*m^2/s^2") # complex unit unit1 =~ unit2 # true if units are compatible unit1.compatible?(unit2) # true if units are compatible unit1 = unit >> "ft" # convert to 'feet' unit3 = unit1 + unit2 # resulting object will have the units of unit1 unit1 === unit2 # true if units and quantity are the same, even if 'equivalent' by <=> unit.convert_to('ft') # convert (unit1 + unit2).convert_to('ft') # converts result to 'ft'
-
require 'units' three_meters = 3.meters two_meters = 2.m one_inch = 1.inch 3.meters.to_inches # => 118.1103 inch 10.inches.to_mm # => 254.0 millimeter
-
require 'unitwise/ext' 1.yard == (1.foot * 3) # => true 1.quart < 1.liter # => true 2.meter + 3.inch - 1.yard # => <Unitwise::Measurement 1.1618 meter> 1.convert_to('kg.m2/s2') == 1.joule # => true (20.kg * 9.8.convert_to('m/s2')).to_pound_force # => <Unitwise::Measurement 44.06255284754326 pound_force> (300.horsepower * 60.second).to_calorie # => <Unitwise::Measurement 3208077.8414151203 calorie>
-
Like another poster, I had trouble getting this working. However, you can see Jörg W Mittag's answer for usage.
As the author of Unitwise, it might be obvious that it's my favorite out of the group. I encourage you to at least check it out, though.
OTHER TIPS
Try awesome Alchemist.
......
Take a look at Tom Sawyer's Van/Unit
This is from the homepage:
require 'van/units'
include Units
1.mile.to(feet)
1.acre.to(yd**2)
1.acre.to(sq_yd)
1.gallon.to(self.L)
1.lb.to(kg)
1.m.s.to(m.s)
1.sq_mi.to(km**2)
1.mile.to(km)
1.usd.to(twd)
1.bit/s + 8.bytes/s
Try gem install sy
require 'sy'
( 5.g * # a bullet of 5g
500.m.s(-1) ** 2 / # flying at a speed of 500m/s has kJ energy:
2 ).in( :kJ ) #=> 0.625
require 'sy/imperial'
1.mile.in :ft #=> 5280.0
1.acre.in :yd² #=> 4840.0
1.gallon.in :l #=> 4.54609
1.lb.in :kg #=> 0.45359237
1.mile².in :km² #=> 2.589988110336
SY::SPEED_OF_LIGHT.in "furlong.fortnight⁻¹" #=> 1802617499785.2544
I was unable to get Van/units to work - all it reports is:
/Library/Ruby/Gems/1.8/gems/vanunits-1.5.0/lib/van/units/base.rb:493:in `to': incompatible units for operation (TypeError) from unitstest.rb:4
When running
require 'rubygems'
require 'van/units'
include Van::Units puts
1.meter.to(feet)
I spent an hour unsuccessfully attempting to hack the source of van/units.
The older gem on which it is based worked out of the box:
vanunits seems broken. i suggest to try
rubyunits (http://ruby-units.rubyforge.org/ruby-units/)
or
measurements (https://github.com/collectiveidea/measurement)