[ANN] Units for Ruby

I have also created a new library to add units to numbers in Ruby:

gem install units
http://units.rubyforge.org/

It is extremely simple to use:

    require 'units/standard'
    1.lb.to_ounces # => 16.0

    require 'units/currency'
    1.euro.usd # => 1.2545

    1.usd.unit # => :usd
    1.usd.to_yen # => 108.9 # this information is grabbed on the fly
via a SOAP call
    1.usd.to_yet.unit # => :yen

It is also very simple to add both static and dynamic conversions on
your own via add_unit_conversions and add_unit_aliases.

I hope you find this library useful too.

Looking good.

Some volume conversion seems to be wrong thought:

irb(main):007:0> 1.teaspoons.to_cubic_meters ** (1.0 / 3)
=> 58.7601229917626

That's a very deep Olympic size swimming pool!

Trusting google for unit conversion:

[gus@comp tmp]$ ruby get_standard.rb 2>/dev/null
:pints => 0.125,
:milliliters => 0.000264172051,
:cubic_feet => 7.48051945,
:cups => 0.0625,
:microliters => 2.64172051,
:cubic_inches => 0.00432900431,
:liters => 0.264172051,
:cubic_centimeters => 0.000264172051,
:cubic_yards => 201.974025,
:hectoliters => 26.4172051,
:fluid_ounces => 0.0078125,
:cubic_millimeters => 2.64172051,
:gallons => 1,
:deciliters => 0.0264172051,
:tablespoons => 0.00390625,
:cubic_meters => 264.172051,
:quarts => 0.25,
:centiliters => 0.00264172051,
:teaspoons => 0.00130208333,
:cubic_decimeters => 0.264172051,

[gus@comp tmp]$ cat get_standard.rb
require 'units/standard'
require 'net/http'

h = Net::HTTP.new('www.google.com', 80)
Numeric::VOLUME.keys.each do |u|
  v = u.to_s.gsub(/_/, " ")
  resp, data = h.get("/search?q=1+#{v.gsub(/ /, "+")}+in+gallon", nil)
  if data =~ /\(?#{v}\)?\s*=\s*([\d.]+)/
      val = $1
      puts(":%-20s => #{val}," % u)
  else
    $stderr.puts("#{u} failed")
  end
end

Thank you for your library,
Guillaume.

···

On Wed, 2005-09-07 at 07:46 +0900, Lucas Carlson wrote:

I have also created a new library to add units to numbers in Ruby:

gem install units
http://units.rubyforge.org/

It is extremely simple to use:

    require 'units/standard'
    1.lb.to_ounces # => 16.0

    require 'units/currency'
    1.euro.usd # => 1.2545

    1.usd.unit # => :usd
    1.usd.to_yen # => 108.9 # this information is grabbed on the fly
via a SOAP call
    1.usd.to_yet.unit # => :yen

It is also very simple to add both static and dynamic conversions on
your own via add_unit_conversions and add_unit_aliases.

I hope you find this library useful too.

# gem install units
Attempting local installation of 'units'
Local gem file not found: units*.gem
Attempting remote installation of 'units'
Updating Gem source index for: http://gems.rubyforge.org
Successfully installed units-1.0.1
Installing RDoc documentation for units-1.0.1...

lib/units/base.rb:50:86: ':' not followed by identified or operator

lib/units/currency.rb:20:35: ':' not followed by identified or operator
# ruby --version
ruby 1.9.0 (2005-02-08) [i686-linux]

Are these two errors important?

···

On 9/6/05, Lucas Carlson <lucas@rufy.com> wrote:

I have also created a new library to add units to numbers in Ruby:

gem install units
http://units.rubyforge.org/

It is extremely simple to use:

    require 'units/standard'
    1.lb.to_ounces # => 16.0

    require 'units/currency'
    1.euro.usd # => 1.2545

    1.usd.unit # => :usd
    1.usd.to_yen # => 108.9 # this information is grabbed on the fly
via a SOAP call
    1.usd.to_yet.unit # => :yen

It is also very simple to add both static and dynamic conversions on
your own via add_unit_conversions and add_unit_aliases.

I hope you find this library useful too.

Lucas Carlson wrote:

I have also created a new library to add units to numbers in Ruby:
...
   require 'units/standard'
...
   1.usd.to_yen # => 108.9 # this information is grabbed on the fly
via a SOAP call

I have a feature request. I want to be able to use this through an HTTP
proxy. (I haven't figured out how to do that with the WSDLDriver.)

Cheers,
Dave

Lucas Carlson wrote:

I have also created a new library to add units to numbers in Ruby:

gem install units

  Attempting local installation of 'units'
  Local gem file not found: units*.gem
  Attempting remote installation of 'units'
  Updating Gem source index for: http://gems.rubyforge.org
  /usr/local/pkgs/ruby-1.8.2/lib/ruby/1.8/yaml.rb:119: [BUG] Segmentation fault
  ruby 1.8.2 (2004-12-25) [powerpc-darwin8.2.0]

  Abort trap

I'm running Mac OS 10.4.2 with a readlines-enabled ruby
compiled from source, and FWIW, yaml.rb has,

     118 def YAML.load( io )
     119 yp = @@parser.new.load( io )
     120 end

Regards,

···

--
Bil
http://fun3d.larc.nasa.gov

Very nice,

thanks for releasing!

-g.

···

--
http://www.gmosx.com
http://www.navel.gr
http://www.nitrohq.com

Good catch Guillaume, I have updated Units to 1.0.1 to address this
issue. Nice use of google and Ruby to generate that list!

-Lucas

They are warnings and nothing to worry about. The reason they came
about was because of defining symbols like this:

:"#{from}_to_#{to}"

RDoc doesn't like it, but it is valid Ruby.

-Lucas

':' not followed by identified or operator

The offending code looks like:
  :"some string with #{interpolation}"

It should work to change that to:
  "some string with #{interpolation}".intern

Cheers,
Dave

FWIW, I'm running 1.8.2 also on Mac OS 10.4.2, also compiled from source, and it worked for me. :expressionless:

···

On Sep 7, 2005, at 5:31 AM, Bil Kleb wrote:

I'm running Mac OS 10.4.2 with a readlines-enabled ruby
compiled from source, and FWIW, yaml.rb has,

    118 def YAML.load( io )
    119 yp = @@parser.new.load( io )
    120 end

About using SOAP with an HTTP proxy, see
http://www.ruby-doc.org/stdlib/libdoc/soap/rdoc/classes/SOAP.html#M000011

Oh, that's only RDoc whingeing. I'm glad. I'm sure I have some :""s in
my code, too.

Thanks, Lucas, but I've looked there, and haven't been able to leverage
that information to my advantage.

It bombs out (Errno::ETIMEDOUT) in WSDLDriverFactory#new, before
there's anything to call proxy= (or httpproxy=) on.

Cheers,
Dave

Small caching problem:

The xmethods.net method seems to provide realtime data. Which is cool,
but the data is being cached by symbol names, so:

10.usd.to_yen returns 10*x

and 10.usd.to_jpy returns 10*y

Even though they should technically return the same value.

I doubt it'd affect anyone's actual code since you're likely to use one
or the other, not both, but still... modifying the code to use country
names instead looks like this:

  def lookup_currency(from, to)
    from = @@currency_countries[from]
    to = @@currency_countries[to]
    cache_key = :"#{from}_to_#{to}"
    @@currency_rates[cache_key] ||= @@currency_converter.getRate(from,
to)
    return @@currency_rates[cache_key]
  end

Problem solved.

Thanks for the code btw. :slight_smile: