rails-units 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,212 @@
1
+ Change Log for Ruby-units
2
+ =========================
3
+ 2011-04-23 1.3.0.a * Some internal restructuring
4
+ * Implement specs for core behaviors
5
+ * fixed several bugs found by specs
6
+ * implemented a few new methods for completeness
7
+ * specs run against 1.8.7, 1.9.2-head, jruby, and rubinius(rbx) using rvm
8
+ 1.2.0 * Release 1.2.0 series
9
+ 2010-11-07 1.2.0.a * a bunch of fixes to make ruby-units ruby 1.9 compatible
10
+ (ruby 1.9.3dev (2010-11-07 trunk 29711) [i386-darwin9.8.0])
11
+ 2010-03-16 1.1.5 * another bugfix, and update url to point to github
12
+ 2010-03-15 1.1.4 * fixed a couple of outstanding bugs
13
+ 2007-12-13 1.1.3 * fixed a minor bug with string %
14
+ 2007-12-12 1.1.2 * fixed a bug with format strings
15
+ * detect if ruby 1.8.6 is installed and use its' to_date function
16
+
17
+ 2007-07-14 1.1.1 * fixed bug that would prevent creating '<pound-mass>' units, which
18
+ prevented rounding from working
19
+ * tests do not fail if Uncertain gem is not installed, you just get an
20
+ annoying warning message
21
+
22
+ 2007-01-28 1.1.0 * completely revamped the temperature handling system (see README)
23
+ * fixed some spelling errors in some units
24
+ * fixed to_datetime and to_date to convert durations to datetimes and dates'
25
+
26
+ 2007-01-24 1.0.2 * Minor changes in the way powers are calculated to support Uncertain
27
+ numbers better.
28
+ * Fixed parsing bug with Uncertain Numbers
29
+ * added resolution / typography units (pixels, points, pica)
30
+ Note that 'pt' means 'pints' and not 'points'
31
+ * added some pressure units ('inHg' & 'inH2O')
32
+ * changed default abbreviation of 'knots' to 'kt'
33
+ * Changed directory layout
34
+ * fixed a minor bug with Time.to_date so comparisons work properly
35
+
36
+ 2007-01-17 1.0.1 * Force units are now defined correctly.
37
+
38
+ 2007-01-12 1.0.0 * Improved handling of complex numbers. Now you can specify
39
+ '1+1i mm'.unit to get a complex unit.
40
+ * Taking the root of a negative unit will give you a complex unit
41
+ * fixed unary minus to work again
42
+ * Math.hypot now takes units. Both parameters must be the compatible
43
+ units or it will assert. Units will be converted to a common base
44
+ before use.
45
+ * Can now specify units in rational numbers, i.e., '1/4 cup'.unit
46
+ * Seems like a good time to move to 1.0 status
47
+
48
+ 2006-12-15 0.3.9 * forgot to increment the version in the gem file..ooops.
49
+
50
+ 2006-12-15 0.3.8 * Any object that supports a 'to_unit' method will now be
51
+ automatically coerced to a unit during math operations.
52
+
53
+ 2006-12-14 0.3.7 * improved handling of percents and added a 'wt%' unit
54
+ equivalent to 1 g/dl.
55
+ * Improved handling for units with non-alphanumeric names
56
+ (like ' for feet, # for pound)
57
+ * Now you can enter durations as "HH:MM:SS, usec" or
58
+ "HH:MM:SS:usec"
59
+
60
+ 2006-12-05 0.3.6 * Fixed bug where (unit/unit).ceil would fail
61
+
62
+ 2006-11-20 0.3.5 * Minor bug fixes
63
+ * to_int now coerces the result to an actual Integer,
64
+ but only works properly for unitless Units.
65
+
66
+ 2006-10-27 0.3.4 * Fixed a few more parsing bugs so that it will properly
67
+ complain about malformed units.
68
+ * Fixed a bug that prevents proper use of percents
69
+ * several minor tweaks
70
+ * some improved Date and DateTime handling
71
+ * can convert between Date, DateTime, and Time objects
72
+ * Time math will now return a DateTime if it goes out of
73
+ range.
74
+
75
+ 2006-10-03 0.3.3 * Apparently I can't do math late at night.
76
+ Fixed a bug that would cause problems when adding
77
+ or subtracting units to a unit with a zero scalar.
78
+ * Date and DateTime objects can be converted to 'units'
79
+
80
+ 2006-10-03 0.3.2 * More minor bug fixes
81
+ (now fixes a minor name collision with rails)
82
+
83
+ 2006-10-02 0.3.1 * minor bug fixes
84
+
85
+ 2006-10-02 0.3.0 * Performance enhanced by caching results of many
86
+ functions (Thanks to Kurt Stephens for pushing this.)
87
+ * Throws an exception if the unit is not recognized
88
+ * units can now identify what 'kind' they are
89
+ (:length, :mass, etc..)
90
+ * New constructors:
91
+ Unit(1,"mm")
92
+ Unit(1,"mm/s")
93
+ Unit(1,"mm","s")
94
+
95
+ 2006-09-22 0.2.3 * added support for date/time parsing with the Chronic gem
96
+ parsing will use Chronic if it is loaded
97
+ * allows Date / Time / DateTime conversions
98
+ * better test coverage
99
+ * The 'string'.to_time returns a Time object
100
+ * 'string'.to_datetime returns a DateTime object
101
+ * 'string'.time returns a Time object or a DateTime if the
102
+ Time object fails
103
+ * 'string'.datetime returns a DateTime or a Time if the
104
+ DateTime fails
105
+
106
+ 2006-09-19 0.2.2 * tweaked temperature handling a bit. Now enter
107
+ temperatures like this:
108
+ '0 tempC'.unit #=> 273.15 degK
109
+ They will always be converted to kelvin to avoid
110
+ problems when temperatures are used in equations.
111
+ * added Time.in("5 min")
112
+ * added Unit.to_unit to simplify some calls
113
+
114
+ 2006-09-18 0.2.1 * Trig math functions (sin, cos, tan, sinh, cosh, tanh)
115
+ accept units that can be converted to radians
116
+ Math.sin("90 deg".unit) => 1.0
117
+ * Date and DateTime can be offset by a time unit
118
+ (Date.today + "1 day".unit) => 2006-09-19
119
+ Does not work with months since they aren't a consistent
120
+ size
121
+ * Tweaked time usage a bit
122
+ Time.now + "1 hr".unit => Mon Sep 18 11:51:29 EDT 2006
123
+ * can output time in 'hh:mm:ss' format by using
124
+ 'unit.to_s(:time)'
125
+ * added time helper methods
126
+ ago,
127
+ since(Time/DateTime),
128
+ until(Time/DateTime),
129
+ from(Time/DateTime),
130
+ before(Time/DateTime), and
131
+ after(Time/DateTime)
132
+ * Time helpers also work on strings. In this case they
133
+ are first converted to units
134
+ '5 min'.from_now
135
+ '1 week'.ago
136
+ 'min'.since(time)
137
+ 'min'.until(time)
138
+ '1 day'.from()
139
+ * Can pass Strings to time helpers and they will be parsed
140
+ with ParseDate
141
+ * Fixed most parsing bugs (I think)
142
+ * Can pass a strftime format string to to_s to format time
143
+ output
144
+ * can use U'1 mm' or '1 mm'.u to specify units now
145
+
146
+ 2006-09-17 * can now use the '%' format specifier like
147
+ '%0.2f' % '1 mm'.unit #=> '1.00 mm'
148
+ * works nicely with time now.
149
+ '1 week'.unit + Time.now => 1.159e+09 s
150
+ Time.at('1.159e+09 s'.unit)
151
+ => Sat Sep 23 04:26:40 EDT 2006
152
+ "1.159e9 s".unit.time
153
+ => Sat Sep 23 04:26:40 EDT 2006
154
+ * Time.now.unit => 1.159e9 s
155
+ * works well with 'Uncertain' numerics
156
+ (www.rubyforge.org/projects/uncertain)
157
+ * Improved parsing
158
+
159
+ 2006-08-28 0.2.0 * Added 'ruby_unit.rb' file so that requires will still
160
+ work if the wrong name is used
161
+ * Added 'to' as an alias to '>>' so conversions can be
162
+ done as '1 m'.unit.to('1 cm')
163
+ * Added ability to convert temperatures to absolute values
164
+ using the following syntax:
165
+ '37 degC'.unit.to('tempF') #=> '98.6 degF'.unit
166
+ * Tweaked abbreviations a bit. 'ton' is now 'tn' instead
167
+ of 't'. It was causing parse collisions with 'atm'.
168
+ * fixed a bug in term elimination routine
169
+ * fixed a bug in parsing of powers, and added support for
170
+ 'm**2' format
171
+ * Added support for taking roots of units. Just
172
+ exponentiate with a fraction (0.5, 1.0/3, 0.25)
173
+ * renamed 'quantity' to 'scalar'
174
+ * any type of Numeric can be used to initialize a Unit,
175
+ although this can't really be done with a string
176
+ * Units can not be forced to a float using to_f unless
177
+ they are unitless. This prevents some math functions
178
+ from forcing the conversion. To get the scalar, just
179
+ use 'unit.scalar'
180
+ * 'inspect' returns string representation
181
+ * better edge-case detection with math functions.
182
+ "0 mm".unit**-1 now throws a ZeroDivisionError exception
183
+ * Ranges can make a series of units, so long as the end
184
+ points have integer scalars.
185
+ * Fixed a parsing bug with feet/pounds and scientific
186
+ numbers
187
+
188
+ 2006-08-22 0.1.1 * Added new format option "1 mm".to_unit("in") now
189
+ converts the result to the indicated units
190
+ * Fixed some naming issues so that the gem name matches
191
+ the require name.
192
+ * Added CHANGELOG
193
+ * Improved test coverage (100% code coverage via RCov)
194
+ * fixed a bug that prevented units with a prefix in the
195
+ denominator from converting properly
196
+ * can use .unit method on a string to create a new unit
197
+ object
198
+ * can now coerce or define units from arrays, strings,
199
+ numerics.
200
+ "1 mm".unit + [1, 'mm'] === "2 mm".unit
201
+ [1,'mm','s'].unit === "1 mm/s".unit
202
+ 2.5.unit === "2.5".unit
203
+ * Added instructions on how to add custom units
204
+
205
+ 2006-08-22 0.1.0 * Initial Release
206
+
207
+
208
+
209
+
210
+
211
+
212
+
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem 'bundler', '~> 1.0'
5
+ gem 'rcov', :platforms => :mri_18
6
+ gem 'jeweler'
7
+ gem 'rspec', '~>2.5'
8
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2007 Kevin C. Olbrich
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ CHANGELOG.txt
2
+ Manifest.txt
3
+ README.md
4
+ LICENSE.txt
5
+ Rakefile
6
+ lib/ruby-units.rb
7
+ lib/ruby_units.rb
8
+ lib/ruby_units/units.rb
9
+ lib/ruby_units/math.rb
10
+ lib/ruby_units/date.rb
11
+ lib/ruby_units/time.rb
12
+ lib/ruby_units/string.rb
13
+ lib/ruby_units/array.rb
14
+ lib/ruby_units/numeric.rb
15
+ lib/ruby_units/object.rb
16
+ lib/ruby_units/array.rb
17
+ lib/ruby_units/complex.rb
18
+ lib/ruby_units/ruby-units.rb
19
+ test/test_ruby-units.rb
@@ -0,0 +1,161 @@
1
+ # Ruby Units
2
+
3
+ This is a version of ruby-units that doesn't conflict with rails 3.
4
+
5
+
6
+ Kevin C. Olbrich, Ph.D.
7
+
8
+ [Sciwerks.com](http://www.sciwerks.com)
9
+
10
+ Project page: [http://github.com/olbrich/ruby-units](http://github.com/olbrich/ruby-units)
11
+
12
+ ## Introduction
13
+ Many technical applications make use of specialized calculations at some point. Frequently, these calculations require unit conversions to ensure accurate results. Needless to say, this is a pain to properly keep track of, and is prone to numerous errors.
14
+
15
+ ## Solution
16
+ The 'Ruby units' gem is designed so simplify the handling of units for scientific calculations. The units of each quantity are specified when a Unit object is created and the Unit class will handle all subsequent conversions and manipulations to ensure an accurate result.
17
+
18
+ ## Installation:
19
+ This package may be installed using: `gem install ruby-units`
20
+
21
+ ## Usage:
22
+ unit = Unit.new("1") # constant only
23
+ unit = Unit.new("mm") # unit only (defaults to a value of 1)
24
+ unit = Unit.new("1 mm") # create a simple unit
25
+ unit = Unit.new("1 mm/s") # a compound unit
26
+ unit = Unit.new("1 mm s^-1") # in exponent notation
27
+ unit = Unit.new("1 kg*m^2/s^2") # complex unit
28
+ unit = Unit.new("1 kg m^2 s^-2") # complex unit
29
+ unit = Unit("1 mm") # shorthand
30
+ unit = "1 mm".to_unit # convert string object
31
+ unit = object.to_unit # convert any object using object.to_s
32
+ unit = U'1 mm'
33
+ unit = u'1 mm'
34
+ unit = '1 mm'.unit
35
+ unit = '1 mm'.u
36
+ unit = '1/4 cup'.unit # Rational number
37
+ unit = '1+1i mm'.unit # Complex Number
38
+
39
+ ## Rules:
40
+ 1. only 1 quantity per unit (with 2 exceptions... 6'5" and '8 lbs 8 oz')
41
+ 2. use SI notation when possible
42
+ 3. avoid using spaces in unit names
43
+
44
+ ## Unit compatability:
45
+ Many methods require that the units of two operands are compatible. Compatible units are those that can be easily converted into each other, such as 'meters' and 'feet'.
46
+
47
+ unit1 =~ unit2 #=> true if units are compatible
48
+
49
+ ## Unit Math:
50
+ Unit#+() # Add. only works if units are compatible
51
+ Unit#-() # Subtract. only works if units are compatible
52
+ Unit#*() # Multiply.
53
+ Unit#/() # Divide.
54
+ Unit#**() # Exponentiate. Exponent must be an integer, can be positive, negative, or zero
55
+ Unit#inverse # Returns 1/unit
56
+ Unit#abs # Returns absolute value of the unit quantity. Strips off the units
57
+ Unit#ceil # rounds quantity to next highest integer
58
+ Unit#floor # rounds quantity down to next lower integer
59
+ Unit#round # rounds quantity to nearest integer
60
+ Unit#to_int # returns the quantity as an integer
61
+
62
+ Unit will coerce other objects into a Unit if used in a formula. This means that ..
63
+
64
+ Unit("1 mm") + "2 mm" == Unit("3 mm")
65
+
66
+ This will work as expected so long as you start the formula with a Unit object.
67
+
68
+ ## Conversions & comparisons
69
+ Units can be converted to other units in a couple of ways.
70
+
71
+ unit1 = unit >> "ft" # convert to 'feet'
72
+ unit >>= "ft" # convert and overwrite original object
73
+ unit3 = unit1 + unit2 # resulting object will have the units of unit1
74
+ unit3 = unit1 - unit2 # resulting object will have the units of unit1
75
+ unit1 <=> unit2 # does comparison on quantities in base units, throws an exception if not compatible
76
+ unit1 === unit2 # true if units and quantity are the same, even if 'equivalent' by <=>
77
+ unit.to('ft') # convert
78
+ unit1 + unit2 >> "ft" # converts result of math to 'ft'
79
+ (unit1 + unit2).to('ft') # converts result to 'ft'
80
+
81
+ Any object that defines a 'to_unit' method will be automatically coerced to a unit during calculations.
82
+
83
+ ## Text Output
84
+ Units will display themselves nicely based on the preferred abbreviation for the units and prefixes.
85
+ Since Unit implements a Unit#to_s, all that is needed in most cases is:
86
+
87
+ "#{Unit.new('1 mm')}" #=> "1 mm"
88
+
89
+ The to_s also accepts some options.
90
+
91
+ Unit.new('1.5 mm').to_s("%0.2f") # "1.50 mm". Enter any valid format
92
+ string. Also accepts strftime format
93
+ U('1.5 mm').to_s("in") # converts to inches before printing
94
+ U("2 m").to_s(:ft) # returns 6'7"
95
+ U("100 kg").to_s(:lbs) # returns 220 lbs, 7 oz
96
+
97
+
98
+ ## Time Helpers
99
+ Time, Date, and DateTime objects can have time units added or subtracted.
100
+
101
+ Time.now + "10 min".unit
102
+
103
+ Several helpers have also been defined.
104
+ Note: If you include the 'Chronic' gem, you can specify times in natural
105
+ language.
106
+
107
+ 'min'.since('9/18/06 3:00pm')
108
+ 'min'.before('9/18/08 3:00pm')
109
+ 'days'.until('1/1/07')
110
+ '5 min'.from(Time.now)
111
+ '5 min'.from_now
112
+ '5 min'.before_now
113
+ '5 min'.before(Time.now)
114
+ '10 min'.ago
115
+
116
+ Durations may be entered as 'HH:MM:SS, usec' and will be returned in 'hours'.
117
+
118
+ '1:00'.unit #=> 1 h
119
+ '0:30'.unit #=> 0.5 h
120
+ '0:30:30'.unit #=> 0.5 h + 30 sec
121
+
122
+ If only one ":" is present, it is interpreted as the separator between hours and minutes.
123
+
124
+ ## Ranges
125
+ [U('0 h')..U('10 h')].each {|x| p x}
126
+ works so long as the starting point has an integer scalar
127
+
128
+ ## Math functions
129
+ All Trig math functions (sin, cos, sinh, hypot...) can take a unit as their parameter. It will be converted to radians and then used if possible.
130
+
131
+ ## Temperatures
132
+ Ruby-units makes a distinction between a temperature (which technically is a property) and degrees of temperature (which temperatures are measured in).
133
+
134
+ Temperature units (i.e., 'tempK') can be converted back and forth, and will take into account the differences in the zero points of the various scales. Differential temperature (e.g., '100 degC'.unit) units behave like most other units.
135
+
136
+ '37 tempC'.unit >> 'tempF' #=> 98.6 tempF
137
+
138
+ Ruby-units will raise an exception if you attempt to create a temperature unit that would fall below absolute zero.
139
+
140
+ Unit math on temperatures is fairly limited.
141
+
142
+ '100 tempC'.unit + '10 degC'.unit # '110 tempC'.unit
143
+ '100 tempC'.unit - '10 degC'.unit # '90 tempC'.unit
144
+ '100 tempC'.unit + '50 tempC'.unit # exception
145
+ '100 tempC'.unit - '50 tempC'.unit # '50 degC'.unit
146
+ '50 tempC'.unit - '100 tempC'.unit # '-50 degC'.unit
147
+ '100 tempC'.unit * [scalar] # '100*scalar tempC'.unit
148
+ '100 tempC'.unit / [scalar] # '100/scalar tempC'.unit
149
+ '100 tempC'.unit * [unit] # exception
150
+ '100 tempC'.unit / [unit] # exception
151
+ '100 tempC'.unit ** N # exception
152
+
153
+ '100 tempC'.unit >> 'degC' #=> '100 degC'.unit
154
+ This conversion references the 0 point on the scale of the temperature unit
155
+
156
+ '100 degC'.unit >> 'tempC' #=> '-173 tempC'.unit
157
+ These conversions are always interpreted as being relative to absolute zero.
158
+ Conversions are probably better done like this...
159
+
160
+ '0 tempC'.unit + '100 degC'.unit #=> '100 tempC'.unit
161
+
@@ -0,0 +1,83 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require './lib/ruby-units'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "ruby-units"
10
+ gem.summary = %Q{A class that performs unit conversions and unit math}
11
+ gem.description = %Q{Provides classes and methods to perform unit math and conversions}
12
+ gem.authors = ["Kevin Olbrich, Ph.D."]
13
+ gem.email = ["kevin.olbrich+ruby_units@gmail.com"]
14
+ gem.homepage = "https://github.com/olbrich/ruby-units"
15
+ gem.files.exclude(".*")
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ begin
23
+ require 'rcov/rcovtask'
24
+ desc "Generate code coverage"
25
+ Rcov::RcovTask.new do |t|
26
+ t.test_files = FileList['test/test*.rb']
27
+ #t.verbose = true # uncomment to see the executed command
28
+ end
29
+ rescue LoadError
30
+ end
31
+
32
+ begin
33
+ require 'rspec/core/rake_task'
34
+
35
+ desc "Run specs"
36
+ RSpec::Core::RakeTask.new
37
+
38
+ desc "Run all specs with rcov"
39
+ RSpec::Core::RakeTask.new("spec:rcov") do |t|
40
+ t.rcov = true
41
+ t.rcov_opts = %w{--exclude osx\/objc,gems\/,spec\/,features\/}
42
+ end
43
+ rescue LoadError
44
+ end
45
+
46
+
47
+ desc "Run unit tests"
48
+ Rake::TestTask.new do |t|
49
+ t.libs << "test"
50
+ t.test_files = FileList['test/test*.rb']
51
+ end
52
+
53
+ task :specs => :spec
54
+
55
+ desc "Run tests against several ruby versions, requires rvm"
56
+ task :multitest do
57
+ rubies = %w{
58
+ ruby-1.8.7@ruby-units
59
+ ruby-1.8.7@ruby-units-with-chronic
60
+ ruby-1.9.2-head@ruby-units
61
+ ruby-1.9.2-head@ruby-units-with-chronic
62
+ rbx-head@ruby-units
63
+ jruby-head@ruby-units
64
+ }
65
+ exec "rvm #{rubies.join(',')} tests"
66
+ end
67
+
68
+ desc "Run specs against several ruby versions, requires rvm"
69
+ task :multispec do
70
+ rubies = %w{
71
+ ruby-1.8.7@ruby-units
72
+ ruby-1.8.7@ruby-units-with-chronic
73
+ ruby-1.9.2-head@ruby-units
74
+ ruby-1.9.2-head@ruby-units-with-chronic
75
+ rbx-head@ruby-units
76
+ jruby-head@ruby-units
77
+ }
78
+ exec "rvm #{rubies.join(',')} specs"
79
+ end
80
+
81
+ task :default => :test
82
+
83
+ task :tests => :test