alchemist 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 971b2a4f87be414e30ada4d1f1f34465c634fe60
4
+ data.tar.gz: d997c55e956f6d2174712a7a9f9fa566a793abf3
5
+ SHA512:
6
+ metadata.gz: cf02dbbd813adbdbaa066e712213fe1e09c751d87507b2b8bdac5d67531ac6e7d7b9eada8d090258dcbfae0ee2c818c279e67c11ce0d6ac6498ed2e3f02eaacb
7
+ data.tar.gz: 4d5c6dd3011d8c984e7b9eda8df286e92489b6c9f49235b4dca1e05137b9931130c090698f7d8e419e9d62d5fa18ce0f470a23b146f95ee8e95624f7c2a77655
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ *.gem
3
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ alchemist (0.1.4)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.0.8)
10
+ method_source (0.8.1)
11
+ pry (0.9.12)
12
+ coderay (~> 1.0.5)
13
+ method_source (~> 0.8)
14
+ slop (~> 3.4)
15
+ rake (10.0.3)
16
+ slop (3.4.3)
17
+
18
+ PLATFORMS
19
+ ruby
20
+
21
+ DEPENDENCIES
22
+ alchemist!
23
+ pry
24
+ rake
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 halogenandtoast
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,121 @@
1
+ Alchemist
2
+ =========
3
+
4
+ [![Build Status](https://travis-ci.org/halogenandtoast/alchemist.png?branch=master)](https://travis-ci.org/halogenandtoast/alchemist)
5
+ [![Code Climate](https://codeclimate.com/github/halogenandtoast/alchemist.png)](https://codeclimate.com/github/halogenandtoast/alchemist)
6
+
7
+ Doing conversions for you so you don’t have to google them and making
8
+ code more readable.
9
+
10
+ Having code that looks like this is meaningless
11
+
12
+ miles = 8 * 1609.344
13
+
14
+ You could add comments
15
+
16
+ miles = 8 * 1609.344 # converting meters to miles
17
+
18
+ But why not have this!
19
+
20
+ 8.meters.to.miles
21
+
22
+ You can even perform mathematical operations
23
+
24
+ 10.kilometers + 1.mile # 11.609344 kilometers
25
+
26
+ Handling bytes now works according to the JEDEC memory standard
27
+
28
+ 1.kb.to.b.to_f == 1024.0
29
+
30
+ To switch to the IEC memory standard, force SI units with
31
+
32
+ Alchemist::use_si = true
33
+
34
+ <strong>You may also register your own units</strong>
35
+
36
+ Alchemist.register(:distance, [:beard_second, :beard_seconds], 5.angstroms)
37
+
38
+ Thanks to <a href='http://github.com/simonmenke'>simonmenke</a> you can
39
+ now do comparisons without having to convert to floats like so:
40
+
41
+ 5.grams == 0.005.kilograms
42
+
43
+ Installation
44
+ ------------
45
+
46
+ gem install alchemist
47
+
48
+ Usage
49
+ -----
50
+
51
+ require 'rubygems'
52
+ require 'alchemist'
53
+
54
+ Or if you’re using rails
55
+
56
+ gem 'alchemist'
57
+
58
+ Alchemist has conversions for:
59
+ ------------------------------
60
+
61
+ ### Distance
62
+
63
+ - metres or meters
64
+ - fermis
65
+ - microns
66
+ - chains
67
+ - inches
68
+ - microinches
69
+ - mils
70
+ - rods
71
+ - leagues
72
+ - feet
73
+ - yards
74
+ - miles
75
+ - astronomical\_units
76
+ - light\_years
77
+ - parsecs
78
+ - nautical\_miles
79
+ - admirality\_miles
80
+ - fathoms
81
+ - cable\_lengths
82
+ - angstroms
83
+ - picas
84
+ - printer\_picas
85
+ - points
86
+ - printer\_points
87
+
88
+ ### Mass
89
+
90
+ - grams or grammes
91
+ - carats
92
+ - ounces
93
+ - pennyweights
94
+ - pounds
95
+ - troy\_pounds or apothecary\_pounds
96
+ - slugs
97
+ - assay\_tons
98
+ - metric\_tons
99
+ - tons or short\_tons
100
+
101
+ ### Volume
102
+
103
+ - litres or liters
104
+ - barrels
105
+ - bushels
106
+ - cubic\_meters
107
+ - cups
108
+ - imperial\_fluid\_ounces
109
+ - fluid\_ounces
110
+ - imperial\_gallons
111
+ - gallons
112
+ - imperial\_gills
113
+ - gills
114
+ - pints
115
+ - liquid\_pints
116
+ - quarts
117
+ - liquid\_quarts
118
+ - tablespoons
119
+ - teaspoons
120
+
121
+ ### And many more checkout **lib/alchemist.rb** for the rest
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
+ require 'bundler/gem_tasks'
1
2
  require 'rake'
2
3
  require 'rake/testtask'
3
- require 'rake/gempackagetask'
4
4
 
5
5
  task :default => [:test]
6
6
  task :test => ['test:units']
@@ -13,9 +13,3 @@ namespace :test do
13
13
  test.verbose = true
14
14
  end
15
15
  end
16
-
17
- eval("$specification = begin; #{IO.read('alchemist.gemspec')}; end")
18
- Rake::GemPackageTask.new($specification) do |package|
19
- package.need_zip = true
20
- package.need_tar = true
21
- end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'alchemist/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'alchemist'
8
+ gem.version = Alchemist::VERSION
9
+ gem.authors = ["Matthew Mongeau"]
10
+ gem.email = ["halogenandtoast@gmail.com"]
11
+ gem.homepage = 'http://github.com/halogenandtoast/alchemist'
12
+ gem.summary = 'Conversions... like you\'ve never seen them before!'
13
+ gem.description = 'Conversions... like you\'ve never seen them before!!'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.add_development_dependency 'rake'
20
+ end
@@ -1,558 +1,96 @@
1
+ require "alchemist/units"
2
+ require "alchemist/compound_numeric_conversion"
3
+ require "alchemist/numeric_conversion"
4
+ require "alchemist/numeric_ext"
5
+
1
6
  module Alchemist
2
- @use_si = false
3
- class << self
4
- attr_accessor :use_si
7
+ def self.measurement value, unit, exponent = 1.0
8
+ NumericConversion.new value, unit, exponent
5
9
  end
6
10
 
7
- @@si_units = %w[m meter metre meters metres liter litre litres liters l L farad farads F coulombs C gray grays Gy siemen siemens S mhos mho ohm ohms volt volts V ]
8
- @@si_units += %w[joule joules J newton newtons N lux lx henry henrys H b B bits bytes bit byte lumen lumens lm candela candelas cd]
9
- @@si_units += %w[tesla teslas T gauss Gs G gram gramme grams grammes g watt watts W pascal pascals Pa]
10
- @@si_units += %w[becquerel becquerels Bq curie curies Ci]
11
- @@operator_actions = {}
12
- @@conversion_table = {
13
- :absorbed_radiation_dose => {
14
- :gray => 1.0, :grays => 1.0, :Gy => 1.0,
15
- :rad => 1.0e-2, :rads => 1.0e-2
16
- },
17
- :angles => {
18
- :radian => 1.0, :radians => 1.0,
19
- :degree => Math::PI / 180.0, :degrees => Math::PI / 180.0,
20
- :arcminute => Math::PI / 10800.0, :arcminutes => Math::PI / 10800.0,
21
- :arcsecond => Math::PI / 648000.0, :arcseconds => Math::PI / 648000.0,
22
- :mil => 9.817477e-4, :mils => 9.817477e-4,
23
- :revolution => Math::PI * 2.0, :revolutions => Math::PI * 2.0,
24
- :circle => Math::PI * 2.0, :circles => Math::PI * 2.0,
25
- :right_angle => Math::PI / 2.0, :right_angles => Math::PI / 2.0,
26
- :grad => Math::PI / 200.0, :grade => Math::PI / 200.0, :gradian => Math::PI / 200.0, :gon => Math::PI / 200.0, :grads => Math::PI / 200.0, :grades => Math::PI / 200.0, :gradians => Math::PI / 200.0, :gons => Math::PI / 200.0,
27
- #unusual measurements
28
- :furman => 9.58737992858887e-5, :furmans => 9.58737992858887e-5
29
- },
30
- :area => {
31
- :square_meter => 1.0, :square_meters => 1.0, :square_metre => 1.0, :square_metres => 1.0,
32
- :acre => 4046.85642, :acres => 4046.85642,
33
- :are => 1.0e+2, :ares => 1.0e+2, :a => 1.0e+2,
34
- :barn => 1.0e-28, :barns => 1.0e-28, :b => 1.0e-28,
35
- :circular_mil => 5.067075e-10, :circular_mils => 5.067075e-10,
36
- :hectare => 1.0e+4, :hectares => 1.0e+4, :ha => 1.0e+4,
37
- :square_foot => 9.290304e-2, :square_feet => 9.290304e-2,
38
- :square_inch => 6.4516e-4, :square_inches => 6.4516e-4,
39
- :square_mile => 2.589988e+6, :square_miles => 2.589988e+6,
40
- :square_yard => 0.83612736, :square_yards => 0.83612736
41
- },
42
- :capacitance => {
43
- :farad => 1.0, :farads => 1.0, :F => 1.0,
44
- :abfarad => 1.0e+9, :emu_of_capacitance => 1.0e+9, :abfarads => 1.0e+9, :emus_of_capacitance => 1.0e+9,
45
- :statfarad => 1.112650e-12, :esu_of_capacitance => 1.112650e-12, :statfarads => 1.112650e-12, :esus_of_capacitance => 1.112650e-12
46
- },
47
- :density => {
48
- :specific_gravity => 1, :sg => 1,
49
- :brix => [Proc.new{ |d| -261.3 / (d - 261.3) }, Proc.new{ |d| 261.3 - (261.3 / d) }],
50
- :plato => [Proc.new{ |d| -260.0 / (d - 260.0) }, Proc.new{ |d| 260.0 - (260.0 / d) }],
51
- :baume => [Proc.new{ |d| -145.0 / (d - 145.0) }, Proc.new{ |d| 145.0 - (145.0 / d) }]
52
- },
53
- :distance => {
54
- :meter => 1.0, :metres => 1.0, :meters => 1.0, :m => 1.0,
55
- :fermi => 1.0e-15, :fermis => 1.0e-15,
56
- :micron => 1.0e-6, :microns => 1.0e-6,
57
- :chain => 20.1168, :chains => 20.1168,
58
- :inch => 25.4e-3, :inches => 25.4e-3, :in => 25.4e-3,
59
- :microinch => 2.54e-8, :microinches => 2.54e-8,
60
- :mil => 2.54e-05, :mils => 2.54e-05,
61
- :rod => 5.029210, :rods => 5.029210,
62
- :league => 5556, :leagues => 5556,
63
- :foot => 0.3048, :feet => 0.3048, :ft => 0.3048,
64
- :yard => 0.9144, :yards => 0.9144, :yd => 0.9144,
65
- :mile =>1609.344, :miles =>1609.344, :mi => 1609.344,
66
- :astronomical_unit => 149.60e+9, :astronomical_units => 149.60e+9, :au => 149.60e+9, :ua => 149.60e+9,
67
- :light_year => 9.461e+15, :light_years => 9.461e+15, :ly => 9.461e+15,
68
- :parsec => 30.857e+15, :parsecs => 30.857e+15,
69
- :nautical_mile => 1852.0, :nautical_miles => 1852.0,
70
- :admirality_mile => 185.3184, :admirality_miles => 185.3184,
71
- :fathom => 1.8288, :fathoms => 1.8288,
72
- :cable_length => 185.2, :cable_lengths => 185.2,
73
- :angstrom => 100.0e-12, :angstroms => 100.0e-12,
74
- :pica => 4.233333e-3, :picas => 4.233333e-3,
75
- :printer_pica => 4.217518e-3, :printer_picas => 4.217518e-3,
76
- :point => 3.527778e-4, :points => 3.527778e-4,
77
- :printer_point => 3.514598e-4, :printer_points => 3.514598e-4,
78
- # unusual mesaurements
79
- :empire_state_building => 449.0, :empire_state_buildings => 449.0,
80
- :sears_tower => 519.0, :sears_towers => 519.0,
81
- :seattle_space_needle => 184.0, :seattle_space_needles => 184.0, :space_needle => 184.0, :space_needles => 184.0,
82
- :statue_of_liberty => 46.0, :statue_of_liberties => 46.0,
83
- :washington_monument => 169.294, :washington_monuments => 169.294,
84
- :eiffel_tower => 324.0, :eiffel_towers => 324.0,
85
- :nelsons_column => 61.5, :nelsons_columns => 61.5,
86
- :blackpool_tower => 158.0, :blackpool_towers => 158.0,
87
- :big_ben => 96.3, :big_bens => 96.3, :clock_tower_of_the_palace_of_westminster => 96.3, :clock_towers_of_the_palace_of_westminster => 96.3,
88
- :st_pauls_cathedral => 108.0, :st_pauls_cathedrals => 108.0,
89
- :toronto_cn_tower => 553.0, :toronto_cn_towers => 553.0, :cn_tower => 553.0, :cn_towers => 553.0,
90
- :circle_of_the_earth => 40075016.686, :equator => 40075016.686, :circles_of_the_earth => 40075016.686, :equators => 40075016.686,
91
- :siriometer => 1.494838e+17, :siriometers => 1.494838e+17,
92
- :football_field => 91.0, :football_fields => 91.0,
93
- :length_of_a_double_decker_bus => 8.4, :height_of_a_double_decker_bus => 4.4,
94
- :smoot => 1.7018, :smoots => 1.7018
95
- },
96
- :dose_equivalent => {
97
- :sievert => 1.0, :sieverts => 1.0, :Si => 1.0,
98
- :rem => 1.0e-2, :rems => 1.0e-2
99
- },
100
- :electric_charge => {
101
- :coulomb => 1.0, :coulombs => 1.0, :C => 1.0,
102
- :abcoulomb => 10.0, :abcoulombs => 10.0,
103
- :ampere_hour => 3.6e+3, :ampere_hours => 3.6e+3,
104
- :faraday => 9.648534e+4, :faradays => 9.648534e+4,
105
- :franklin => 3.335641e-10, :franklins => 3.335641e-10, :Fr => 3.335641e-10,
106
- :statcoulomb => 3.335641e-10, :statcoulombs => 3.335641e-10
107
- },
108
- :electric_conductance => {
109
- :siemen => 1.0, :siemens => 1.0, :S => 1.0, :mho => 1.0,
110
- :abmho => 1.0e+9, :absiemen => 1.0e+9, :absiemens => 1.0e+9,
111
- :statmho => 1.112650e-12, :statsiemen => 1.112650e-12, :statsiemens => 1.112650e-12
112
- },
113
- :electrical_impedance => {
114
- :ohm => 1.0, :ohms => 1.0,
115
- :abohm => 1.0e-9, :emu_of_resistance => 1.0e-9, :abohms => 1.0e-9, :emus_of_resistance => 1.0e-9,
116
- :statohm => 8.987552e+11, :esu_of_resistance => 8.987552e+11, :statohms => 8.987552e+11, :esus_of_resistance => 8.987552e+11
117
- },
118
- :electromotive_force => {
119
- :volt => 1.0, :volts => 1.0, :V => 1.0,
120
- :abvolt => 1.0e-8, :emu_of_electric_potential => 1.0e-8, :abvolts => 1.0e-8, :emus_of_electric_potential => 1.0e-8,
121
- :statvolt => 2.997925e+2, :esu_of_electric_potential => 2.997925e+2, :statvolts => 2.997925e+2, :esus_of_electric_potential => 2.997925e+2
122
- },
123
- :energy => {
124
- :joule => 1.0, :joules => 1.0, :J => 1.0, :watt_second => 1.0, :watt_seconds => 1.0,
125
- :watt_hour => 3.6e+3, :watt_hours => 3.6e+3,
126
- :ton_of_tnt => 4.184e+9, :tons_of_tnt => 4.184e+9,
127
- :therm => 1.05506e+8, :therms => 1.05506e+8,
128
- :us_therm => 1.054804e+8, :us_therms => 1.054804e+8,
129
- :kilowatt_hour => 3.6e+6, :kilowatt_hours => 3.6e+6,
130
- :kilocalorie => 4184.0, :kilocalories => 4184.0,
131
- :calorie => 4.184, :calories => 4.184,
132
- :mean_kilocalorie => 4190, :mean_kilocalories => 4190,
133
- :mean_calorie => 4.190, :mean_calories => 4.190,
134
- :it_kilocalorie => 4186.8, :it_kilocalories => 4186.8,
135
- :it_calorie => 4.1868, :it_calories => 4.1868,
136
- :foot_poundal => 4.214011e-2, :foot_poundals => 4.214011e-2,
137
- :foot_pound_force => 1.355818,
138
- :erg => 1.0e-7, :ergs => 1.0e-7,
139
- :electronvolt => 1.602176e-19, :electronvolts => 1.602176e-19, :eV => 1.602176e-19,
140
- :british_thermal_unit => 1.054350e+3, :british_thermal_units => 1.054350e+3,
141
- :mean_british_thermal_unit => 1.05587e+3, :mean_british_thermal_units => 1.05587e+3,
142
- :it_british_thermal_unit => 1.055056e+3, :it_british_thermal_units => 1.055056e+3,
143
- #unusual measurements
144
- :foe => 1e+44, :foes => 1e+44
145
- },
146
- :frequency => {
147
- :hertz => 1.0, :hz => 1.0, :'Hz' => 1.0,
148
- :revolutions_per_minute => 1/60.0, :rpm => 1/60.0,
149
- :beats_per_minute => 1/60.0, :bpm => 1/60.0
150
- },
151
- :force => {
152
- :newton => 1.0, :newtons => 1.0, :N => 1.0,
153
- :dyne => 1.0e-5, :dynes => 1.0e-5, :dyn => 1.0e-5,
154
- :kilogram_force => 9.80665, :kgf => 9.80665, :kilopond => 9.80665, :kiloponds => 9.80665, :kp => 9.80665,
155
- :kip => 4.448222e+3, :kips => 4.448222e+3,
156
- :ounce_force => 2.780139e-1, :ozf => 2.780139e-1,
157
- :poundal => 1.382550e-1, :poundals => 1.382550e-1,
158
- :pound_force => 4.448222, :lbf => 4.448222,
159
- :ton_force => 8.896443e+3
160
- },
161
- :illuminance => {
162
- :lux => 1.0, :lx => 1.0, :lumens_per_square_metre => 1.0, :lumens_per_square_meter => 1.0, :lumen_per_square_metre => 1.0, :lumen_per_square_meter => 1.0,
163
- :phot => 1.0e+4, :phots => 1.0e+4, :ph => 1.0e+4,
164
- :lumens_per_square_foot => 10.76391, :footcandle => 10.76391, :lumen_per_square_foot => 10.76391, :footcandles => 10.76391
165
- },
166
- :inductance => {
167
- :henry => 1.0, :henrys => 1.0, :H => 1.0,
168
- :abhenrys => 1.0e-9, :emus_of_inductance => 1.0e-9, :abhenry => 1.0e-9, :emu_of_inductance => 1.0e-9,
169
- :stathenrys => 8.987552e+11, :esus_of_inductance => 8.987552e+11, :stathenry => 8.987552e+11, :esu_of_inductance => 8.987552e+11
170
- },
171
- :information_storage => {
172
- :bit => 1.0, :bits => 1.0, :b => 1.0,
173
- :byte => 8.0, :bytes => 8.0, :B => 8.0,
174
- :nibbles => 4.0, :nybbles => 4.0
175
- },
176
- :luminous_flux => {
177
- :lumen => 1.0, :lumens => 1.0, :lm => 1.0
178
- },
179
- :luminous_intensity => {
180
- :candela => 1.0, :candelas => 1.0, :cd => 1.0
181
- },
182
- :magnetic_flux => {
183
- :webers => 1.0, :Wb => 1.0,
184
- :maxwells => 1.0e-8, :Mx => 1.0e-8,
185
- :unit_poles => 1.256637e-7
186
- },
187
- :magnetic_inductance => {
188
- :tesla => 1.0, :teslas => 1.0, :T => 1.0,
189
- :gamma => 1.0e-9, :gammas => 1.0e-9,
190
- :gauss => 1.0e-4, :Gs => 1.0e-4, :G => 1.0e-4
191
- },
192
- :mass => {
193
- :gram => 1.0, :gramme => 1.0, :grams => 1.0, :grammes => 1.0, :g => 1.0,
194
- :carat => 2.0e-1, :carats => 2.0e-1,
195
- :ounce => 2.834952e+1, :ounces => 2.834952e+1, :oz => 2.834952e+1,
196
- :pennyweight => 1.555174, :pennyweights => 1.555174, :dwt => 1.555174,
197
- :pound => 453.59237, :pounds => 453.59237, :lb => 453.59237, :lbs => 453.59237,
198
- :troy_pound => 373.2417, :apothecary_pound => 373.2417, :troy_pounds => 373.2417, :apothecary_pounds => 373.2417,
199
- :slug => 14593.9029, :slugs => 14593.9029,
200
- :assay_ton => 29.1667, :assay_tons => 29.1667, :AT => 29.1667,
201
- :metric_ton => 1000000, :metric_tons => 1000000,
202
- :ton => 907184.74, :tons => 907184.74, :short_tons => 907184.74,
203
- #unusual measurements
204
- :elephant => 5443108.44, :elephants => 5443108.44
205
- },
206
- :power => {
207
- :watt => 1.0, :watts => 1.0, :W => 1.0,
208
- :british_thermal_unit_per_hour => 2.928751e-1, :british_thermal_units_per_hour => 2.928751e-1,
209
- :it_british_thermal_unit_per_hour => 2.930711e-1, :it_british_thermal_units_per_hour => 2.930711e-1,
210
- :british_thermal_unit_per_second => 1.054350e+3, :british_thermal_units_per_second => 1.054350e+3,
211
- :it_british_thermal_unit_per_second => 1.055056e+3, :it_british_thermal_units_per_second => 1.055056e+3,
212
- :calorie_per_minute => 6.973333e-2, :calories_per_minute => 6.973333e-2,
213
- :calorie_per_second => 4.184, :calories_per_second => 4.184,
214
- :erg_per_second => 1.0e-7, :ergs_per_second => 1.0e-7,
215
- :foot_pound_force_per_hour => 3.766161e-4,
216
- :foot_pound_force_per_minute => 2.259697e-2,
217
- :foot_pound_force_per_second => 1.355818,
218
- :horsepower => 7.456999e+2,
219
- :boiler_horsepower => 9.80950e+3,
220
- :electric_horsepower => 7.46e+2,
221
- :metric_horsepower => 7.354988e+2,
222
- :uk_horsepower => 7.4570e+2,
223
- :water_horsepower => 7.46043e+2,
224
- :kilocalorie_per_minute => 6.973333*10, :kilocalories_per_minute => 6.973333*10,
225
- :kilocalorie_per_second => 4.184e+3, :kilocalories_per_second => 4.184e+3,
226
- :ton_of_refrigeration => 3.516853e+3, :tons_of_refrigeration => 3.516853e+3
227
- },
228
- :pressure => {
229
- :pascal => 1.0, :pascals => 1.0, :Pa => 1.0,
230
- :atmosphere => 1.01325e+5, :atmospheres => 1.01325e+5,
231
- :technical_atmosphere => 9.80665e+4, :technical_atmospheres => 9.80665e+4,
232
- :bar => 1.0e+5, :bars => 1.0e+5,
233
- :centimeter_of_mercury => 1.333224e+3, :centimeters_of_mercury => 1.333224e+3,
234
- :centimeter_of_water => 98.0665, :centimeters_of_water => 98.0665, :gram_force_per_square_centimeter => 98.0665,
235
- :dyne_per_square_centimeter => 1.0e-1, :dynes_per_square_centimeter => 1.0e-1,
236
- :foot_of_mercury => 4.063666e+4, :feet_of_mercury => 4.063666e+4,
237
- :foot_of_water => 2.989067e+3, :feet_of_water => 2.989067e+3,
238
- :inch_of_mercury => 3.386389e+3, :inches_of_mercury => 3.386389e+3,
239
- :inch_of_water => 2.490889e+2, :inches_of_water => 2.490889e+2,
240
- :kilogram_force_per_square_centimeter => 9.80665e+4,
241
- :kilogram_force_per_square_meter => 9.80665,
242
- :kilogram_force_per_square_millimeter => 9.80665e+6,
243
- :kip_per_square_inch => 6.894757e+6, :kips_per_square_inch => 6.894757e+6, :ksi => 6.894757e+6,
244
- :millibar => 1.0e+2, :mbar => 1.0e+2, :millibars => 1.0e+2, :mbars => 1.0e+2,
245
- :millimeter_of_mercury => 1.333224e+2, :millimeters_of_mercury => 1.333224e+2,
246
- :millimeter_of_water => 9.80665, :millimeters_of_water => 9.80665,
247
- :poundal_per_square_foot => 1.488164, :poundals_per_square_foot => 1.488164,
248
- :pound_force_per_square_foot => 47.88026,
249
- :pound_force_per_square_inch => 6.894757e+3, :psi => 6.894757e+3,
250
- :torr => 1.333224e+2, :torrs => 1.333224e+2
251
- },
252
- :radioactivity => {
253
- :becquerel => 1.0, :becquerels => 1.0, :Bq => 1.0,
254
- :curie => 3.7e+10, :curies => 3.7e+10, :Ci => 3.7e+10
255
- },
256
- :temperature => {
257
- :kelvin => 1.0, :K => 1.0,
258
-
259
- :celsius => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }], :centrigrade => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }],
260
- :degree_celsius => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }], :degree_centrigrade => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }],
261
- :degrees_celsius => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }], :degrees_centrigrade => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }],
262
- :fahrenheit => [Proc.new{ |t| (t + 459.67) * (5.0/9.0) }, Proc.new{ |t| t * (9.0/5.0) - 459.67 }],
263
- :degree_fahrenheit => [Proc.new{ |t| (t + 459.67) * (5.0/9.0) }, Proc.new{ |t| t * (9.0/5.0) - 459.67 }],
264
- :degrees_fahrenheit => [Proc.new{ |t| (t + 459.67) * (5.0/9.0) }, Proc.new{ |t| t * (9.0/5.0) - 459.67 }],
265
- :rankine => 1.8, :rankines => 1.8
266
- },
267
- :time => {
268
- :second => 1.0, :seconds => 1.0, :s => 1.0,
269
- :minute => 60.0, :minutes => 60.0, :min => 60.0,
270
- :sidereal_minute => 5.983617, :sidereal_minutes => 5.983617,
271
- :hour => 3600.0, :hours => 3600.0, :hr => 3600.0, :h => 3600.0,
272
- :sidereal_hour => 3.590170e+3, :sidereal_hours => 3.590170e+3,
273
- :day => 86400.0, :days => 86400.0,
274
- :sidereal_day => 8.616409e+4, :sidereal_days => 8.616409e+4,
275
- :shake => 1.0e-8, :shakes => 1.0e-8,
276
- :year => 3.1536e+7, :years => 3.1536e+7,
277
- :sidereal_year => 3.155815e+7, :sidereal_years => 3.155815e+7,
278
- :tropical_year => 3.155693e+7, :tropical_years => 3.155693e+7,
279
- #unusual measurements
280
- :jiffy => 0.01, :jiffies => 0.01,
281
- :microfortnight => 1.2096, :microfortnights => 1.2096,
282
- :megaannum => 3.1536e+16, :Ma => 3.1536e+16, :megaannums => 3.1536e+16,
283
- :galactic_year => 7.884e+18, :galactic_years => 7.884e+18, :GY => 7.884e+18
284
- },
285
- :volume => {
286
- :litre => 1.0, :liter => 1.0, :litres => 1.0, :liters => 1.0, :l => 1.0, :L => 1.0,
287
- :barrel => 1.589873e+2, :barrels => 1.589873e+2,
288
- :bushel => 3.523907e+1, :bushels => 3.523907e+1,
289
- :cubic_meter => 1000.0, :cubic_meters => 1000.0,
290
- :cup => 2.365882e-1, :cups => 2.365882e-1,
291
- :imperial_fluid_ounce => 0.0284130742, :imperial_fluid_ounces => 0.0284130742,
292
- :ounce => 0.0295735296, :ounces => 0.0295735296, :fluid_ounce => 0.0295735296, :fluid_ounces => 0.0295735296,
293
- :imperial_gallon => 4.54609, :imperial_gallons => 4.54609,
294
- :gallon => 3.785412, :gallons => 3.785412, :gals => 3.785412, :Gals => 3.785412,
295
- :imperial_gill => 1.420653e-1, :imperial_gills => 1.420653e-1,
296
- :gill => 1.182941e-1, :gills => 1.182941e-1, :gi => 1.182941e-1,
297
- :pint => 5.506105e-1, :pints => 5.506105e-1,
298
- :liquid_pint => 4.731765e-1, :liquid_pints => 4.731765e-1,
299
- :quart => 1.101221, :quarts => 1.101221,
300
- :liquid_quart => 9.463529e-1, :liquid_quarts => 9.463529e-1,
301
- :tablespoon => 0.0147867648, :tablespoons => 0.0147867648,
302
- :teaspoon => 0.00492892159, :teaspoons => 0.00492892159,
303
- #unusual measurements
304
- :sydharb => 5.0e+11, :sydharbs => 5.0e+11
305
- }
306
- }
307
- @@unit_prefixes = {
308
- :googol => 1e+100,
309
- :yotta => 1e+24, :Y => 1e+24,
310
- :zetta => 1e+21, :Z => 1e+21,
311
- :exa => 1e+18, :E => 1e+18,
312
- :peta => 1e+15, :P => 1e+15,
313
- :tera => 1e+12, :T => 1e+12,
314
- :giga => 1e+9, :G => 1e+9,
315
- :mega => 1e+6, :M => 1e+6,
316
- :kilo => 1e+3, :k => 1e+3,
317
- :hecto => 1e+2, :h => 1e+2,
318
- :deca => 10, :da => 10,
319
- :deci => 1e-1, :d => 1e-1,
320
- :centi => 1e-2, :c => 1e-2,
321
- :milli => 1e-3, :m => 1e-3,
322
- :micro => 1e-6, :u => 1e-6,
323
- :nano => 1e-9, :n => 1e-9,
324
- :pico => 1e-12, :p => 1e-12,
325
- :femto => 1e-15, :f => 1e-15,
326
- :atto => 1e-18, :a => 1e-18,
327
- :zepto => 1e-21, :z => 1e-21,
328
- :yocto => 1e-24, :y => 1e-24,
329
-
330
- # binary prefixes
331
-
332
- :kibi => 2.0**10.0, :Ki => 2.0**10.0,
333
- :mebi => 2.0**20.0, :Mi => 2.0**20.0,
334
- :gibi => 2.0**30.0, :Gi => 2.0**30.0,
335
- :tebi => 2.0**40.0, :Ti => 2.0**40.0,
336
- :pebi => 2.0**50.0, :Pi => 2.0**50.0,
337
- :exbi => 2.0**60.0, :Ei => 2.0**60.0,
338
- :zebi => 2.0**70.0, :Zi => 2.0**70.0,
339
- :yobi => 2.0**80.0, :Yi => 2.0**80.0
340
- }
341
-
342
- def from(unit_name)
343
- send(unit_name)
11
+ def self.use_si
12
+ @use_si ||= false
344
13
  end
345
14
 
346
- def self.unit_prefixes
347
- @@unit_prefixes
15
+ def self.use_si= use_si
16
+ @use_si = use_si
348
17
  end
349
18
 
350
19
  def self.conversion_table
351
- @@conversion_table
20
+ @conversion_table ||= ConversionTable.new.load_all
352
21
  end
353
22
 
354
23
  def self.operator_actions
355
- @@operator_actions
24
+ @operator_actions ||= {}
356
25
  end
357
26
 
358
- class CompoundNumericConversion
359
- attr_accessor :numerators, :denominators
360
- def initialize(numerator)
361
- @coefficient = 1 #* numerator.to_f
362
- @numerators = [numerator]
363
- @denominators = []
364
- end
365
- def *(value)
366
- case value
367
- when Numeric
368
- @coefficient *= value
369
- self
370
- when Alchemist::NumericConversion
371
- @numerators << value
372
- return consolidate
373
- end
374
- end
375
-
376
- def consolidate
377
- @numerators.each_with_index do |numerator, n|
378
- @denominators.each_with_index do |denominator, d|
379
- next if numerator.is_a?(Numeric)
380
- next if denominator.is_a?(Numeric)
381
- if (Conversions[numerator.unit_name] & Conversions[denominator.unit_name]).length > 0
382
- value = numerator / denominator
383
- @numerators.delete_at(n)
384
- @denominators.delete_at(d)
385
- @coefficient *= value
386
- end
387
- end
388
- end
389
- if @denominators.length == 0 && @numerators.length == 1
390
- @numerators[0] * @coefficient
391
- elsif @denominators.length == 0 && @numerators.length == 0
392
- @coefficient
393
- else
394
- self
395
- end
396
- end
397
-
398
- def to_s
399
-
400
- end
401
-
402
- def method_missing(method, *attrs, &block)
403
- if Conversions[method]
404
- @denominators << 1.send(method)
405
- consolidate
406
- end
407
- end
27
+ def self.conversions
28
+ @conversions ||= load_conversions
408
29
  end
409
30
 
410
- class NumericConversion
411
- include Comparable
412
-
413
- def per
414
- Alchemist::CompoundNumericConversion.new(self)
415
- end
416
-
417
- def p
418
- per
419
- end
420
-
421
- def to(type = nil)
422
- unless type
423
- self
424
- else
425
- send(type)
426
- end
427
- end
428
- alias_method :as, :to
429
-
430
- def base(unit_type)
431
- if(Alchemist.conversion_table[unit_type][@unit_name].is_a?(Array))
432
- @exponent * Alchemist.conversion_table[unit_type][@unit_name][0].call(@value)
433
- else
434
- @exponent * @value * Alchemist.conversion_table[unit_type][@unit_name]
435
- end
436
- end
437
-
438
- def unit_name
439
- @unit_name
440
- end
31
+ def self.measurement_for name
32
+ conversions[ name.to_sym ]
33
+ end
441
34
 
442
- def to_s
443
- @value.to_s
444
- end
35
+ def self.register(type, names, value)
445
36
 
446
- def value
447
- @value
448
- end
37
+ names = Array(names)
38
+ value = value.is_a?(NumericConversion) ? value.base(type) : value
449
39
 
450
- def to_f
451
- @value
40
+ names.each do |name|
41
+ conversions[name] ||= []
42
+ conversions[name] << type
43
+ Alchemist.conversion_table[type][name] = value
452
44
  end
45
+ end
453
46
 
454
- def ==(other)
455
- (self <=> other) == 0
456
- end
47
+ def self.register_operation_conversions type, other_type, operation, converted_type
48
+ operator_actions[operation] ||= []
49
+ operator_actions[operation] << [type, other_type, converted_type]
50
+ end
457
51
 
458
- def <=>(other)
459
- (self.to_f * @exponent).to_f <=> other.to(@unit_name).to_f
460
- end
52
+ def self.parse_prefix(unit)
53
+ matches = unit.to_s.match(prefix_matcher)
54
+ prefix, parsed_unit = matches.captures
461
55
 
462
- private
463
- def initialize value, unit_name, exponent = 1.0
464
- @value = value.to_f
465
- @unit_name = unit_name
466
- @exponent = exponent
56
+ if prefix && si_units.include?(parsed_unit)
57
+ value = prefixed_value_for(prefix.to_sym, parsed_unit)
58
+ [value, parsed_unit.to_sym]
59
+ else
60
+ [1, unit]
467
61
  end
62
+ end
468
63
 
469
- def method_missing unit_name, *args, &block
470
- exponent, unit_name = Alchemist.parse_prefix(unit_name)
471
- if Conversions[ unit_name ]
472
- types = Conversions[ @unit_name] & Conversions[ unit_name]
473
- if types[0] # assume first type
474
- if(Alchemist.conversion_table[types[0]][unit_name].is_a?(Array))
475
- Alchemist.conversion_table[types[0]][unit_name][1].call(base(types[0]))
476
- else
477
- NumericConversion.new(base(types[0]) / (exponent * Alchemist.conversion_table[types[0]][unit_name]), unit_name)
478
- end
479
- else
480
- raise Exception, "Incompatible Types"
481
- end
482
- else
483
- if args[0] && args[0].is_a?(NumericConversion) && Alchemist.operator_actions[unit_name]
484
- t1 = Conversions[ @unit_name ][0]
485
- t2 = Conversions[ args[0].unit_name ][0]
486
- Alchemist.operator_actions[unit_name].each do |s1, s2, new_type|
487
- if t1 == s1 && t2 == s2
488
- return (@value * args[0].to_f).send(new_type)
489
- end
490
- end
491
- end
492
- if unit_name == :*
493
- if args[0].is_a?(Numeric)
494
- @value *= args[0]
495
- return self
496
- else
497
- raise Exception, "Incompatible Types"
498
- end
499
- end
500
- if unit_name == :/ && args[0].is_a?(NumericConversion)
501
- raise Exception, "Incompatible Types" unless (Conversions[@unit_name] & Conversions[args[0].unit_name]).length > 0
502
- end
503
- args.map!{|a| a.is_a?(NumericConversion) ? a.send(@unit_name).to_f / @exponent : a }
504
- @value = @value.send( unit_name, *args, &block )
505
-
64
+ private
506
65
 
507
- unit_name == :/ ? @value : self
508
- end
509
- end
66
+ def self.use_binary_prefix? unit
67
+ !use_si && measurement_for(unit).include?(:information_storage)
510
68
  end
511
69
 
512
- Conversions = {}
513
- def method_missing unit_name, *args, &block
514
- exponent, unit_name = Alchemist.parse_prefix(unit_name)
515
- Conversions[ unit_name ] || super( unit_name, *args, &block )
516
- NumericConversion.new self, unit_name, exponent
517
- end
518
70
 
519
- def self.register(type, names, value)
520
- names = [names] unless names.is_a?(Array)
521
- value = value.is_a?(NumericConversion) ? value.base(type) : value
522
- names.each do |name|
523
- Conversions[name] ||= []
524
- Conversions[name] << type
525
- Alchemist.conversion_table[type][name] = value
526
- end
71
+ def self.prefix_matcher
72
+ keys = unit_prefixes.keys.map(&:to_s).sort{ |a,b| b.length <=> a.length }
73
+ %r{^(#{keys.join('|')})?(.+)}
527
74
  end
528
75
 
529
- def self.register_operation_conversions type, other_type, operation, converted_type
530
- @@operator_actions[operation] ||= []
531
- @@operator_actions[operation] << [type, other_type, converted_type]
532
- end
533
-
534
- def self.parse_prefix(unit)
535
- @@unit_prefixes.each do |prefix, value|
536
- if unit.to_s =~ /^#{prefix}.+/ && @@si_units.include?(unit.to_s.gsub(/^#{prefix}/,''))
537
- if !(Conversions[ unit.to_s.gsub(/^#{prefix}/,'').to_sym ] & [ :information_storage ]).empty? && !@use_si && value >= 1000.0 && value.to_i & -value.to_i != value
538
- value = 2 ** (10 * (Math.log(value) / Math.log(10)) / 3)
539
- end
540
- return [value, unit.to_s.gsub(/^#{prefix}/,'').to_sym]
541
- end
76
+ def self.prefixed_value_for prefix, unit
77
+ if use_binary_prefix? unit
78
+ binary_prefixes[prefix]
79
+ else
80
+ unit_prefixes[prefix]
542
81
  end
543
- [1.0, unit]
544
82
  end
545
83
 
546
- @@conversion_table.each do |type, conversions|
547
- conversions.each do |name, value|
548
- Conversions[name] ||= []
549
- Conversions[name] << type
84
+ def self.load_conversions
85
+ conversions = {}
86
+ conversion_table.each do |type, table_conversions|
87
+ table_conversions.each do |name, value|
88
+ conversions[name] ||= []
89
+ conversions[name] << type
90
+ end
550
91
  end
92
+ conversions
551
93
  end
552
94
  end
553
95
 
554
- class Numeric
555
- include Alchemist
556
- end
557
-
558
- require 'alchemist/compound'
96
+ require "alchemist/compound"