Skip to content

Commit

Permalink
update README with more current information and examples
Browse files Browse the repository at this point in the history
  • Loading branch information
olbrich committed Jan 2, 2012
1 parent 45d8839 commit 732dc8d
Showing 1 changed file with 68 additions and 55 deletions.
123 changes: 68 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,17 @@ This package may be installed using: `gem install ruby-units`

## Usage:
unit = Unit.new("1") # constant only
unit = Unit.new("mm") # unit only (defaults to a value of 1)
unit = Unit.new("1 mm") # create a simple unit
unit = Unit.new("1 mm/s") # a compound unit
unit = Unit.new("1 mm s^-1") # in exponent notation
unit = Unit.new("1 kg*m^2/s^2") # complex unit
unit = Unit.new("1 kg m^2 s^-2") # complex unit
unit = Unit("mm") # unit only (defaults to a scalar of 1)
unit = Unit("1 mm") # create a simple unit
unit = Unit("1 mm/s") # a compound unit
unit = Unit("1 mm s^-1") # in exponent notation
unit = Unit("1 kg*m^2/s^2") # complex unit
unit = Unit("1 kg m^2 s^-2") # complex unit
unit = Unit("1 mm") # shorthand
unit = "1 mm".to_unit # convert string object
unit = object.to_unit # convert any object using object.to_s
unit = U'1 mm'
unit = u'1 mm'
unit = '1 mm'.unit
unit = '1 mm'.u
unit = '1/4 cup'.unit # Rational number
unit = '1+1i mm'.unit # Complex Number
unit = Unit('1/4 cup') # Rational number
unit = Unit('1+1i mm') # Complex Number

## Rules:
1. only 1 quantity per unit (with 2 exceptions... 6'5" and '8 lbs 8 oz')
Expand All @@ -41,7 +37,8 @@ This package may be installed using: `gem install ruby-units`
## Unit compatability:
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'.

unit1 =~ unit2 #=> true if units are compatible
unit1 =~ unit2 #=> true if units are compatible
unit1.compatible?(unit2) #=> true if units are compatible

## Unit Math:
Unit#+() # Add. only works if units are compatible
Expand All @@ -65,61 +62,54 @@ This will work as expected so long as you start the formula with a Unit object.
## Conversions & comparisons
Units can be converted to other units in a couple of ways.

unit1 = unit >> "ft" # convert to 'feet'
unit >>= "ft" # convert and overwrite original object
unit3 = unit1 + unit2 # resulting object will have the units of unit1
unit3 = unit1 - unit2 # resulting object will have the units of unit1
unit1 <=> unit2 # does comparison on quantities in base units, throws an exception if not compatible
unit1 === unit2 # true if units and quantity are the same, even if 'equivalent' by <=>
unit.to('ft') # convert
unit1 + unit2 >> "ft" # converts result of math to 'ft'
(unit1 + unit2).convert_to('ft') # converts result to 'ft'
unit1 = unit >> "ft" # convert to 'feet'
unit >>= "ft" # convert and overwrite original object
unit3 = unit1 + unit2 # resulting object will have the units of unit1
unit3 = unit1 - unit2 # resulting object will have the units of unit1
unit1 <=> unit2 # does comparison on quantities in base units, throws an exception if not compatible
unit1 === unit2 # true if units and quantity are the same, even if 'equivalent' by <=>
unit.convert_to('ft') # convert
unit1 + unit2 >> "ft" # converts result of math to 'ft'
(unit1 + unit2).convert_to('ft') # converts result to 'ft'

Any object that defines a 'to_unit' method will be automatically coerced to a unit during calculations.

## Text Output
Units will display themselves nicely based on the preferred abbreviation for the units and prefixes.
Units will display themselves nicely based on the display_name for the units and prefixes.
Since Unit implements a Unit#to_s, all that is needed in most cases is:

"#{Unit('1 mm')}" #=> "1 mm"

The to_s also accepts some options.

Unit.new('1.5 mm').to_s("%0.2f") # "1.50 mm". Enter any valid format
Unit('1.5 mm').to_s("%0.2f") # "1.50 mm". Enter any valid format
string. Also accepts strftime format
U('1.5 mm').to_s("in") # converts to inches before printing
U("2 m").to_s(:ft) # returns 6'7"
U("100 kg").to_s(:lbs) # returns 220 lbs, 7 oz
Unit('1.5 mm').to_s("in") # converts to inches before printing
Unit("2 m").to_s(:ft) # returns 6'7"
Unit("100 kg").to_s(:lbs) # returns 220 lbs, 7 oz


## Time Helpers
Time, Date, and DateTime objects can have time units added or subtracted.

Time.now + "10 min".unit
Time.now + Unit("10 min")

Several helpers have also been defined.
Note: If you include the 'Chronic' gem, you can specify times in natural
language.

Unit('min').since(DateTime.parse('9/18/06 3:00pm'))
'min'.before('9/18/08 3:00pm')
'days'.until('1/1/07')
'5 min'.from(Time.now)
'5 min'.from_now
'5 min'.before_now
'5 min'.before(Time.now)
'10 min'.ago

Durations may be entered as 'HH:MM:SS, usec' and will be returned in 'hours'.

'1:00'.unit #=> 1 h
'0:30'.unit #=> 0.5 h
'0:30:30'.unit #=> 0.5 h + 30 sec
Unit('1:00') #=> 1 h
Unit('0:30') #=> 0.5 h
Unit('0:30:30') #=> 0.5 h + 30 sec

If only one ":" is present, it is interpreted as the separator between hours and minutes.

## Ranges
[U('0 h')..U('10 h')].each {|x| p x}
[Unit('0 h')..Unit('10 h')].each {|x| p x}
works so long as the starting point has an integer scalar

## Math functions
Expand All @@ -130,29 +120,52 @@ Ruby-units makes a distinction between a temperature (which technically is a pro

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.

'37 tempC'.unit >> 'tempF' #=> 98.6 tempF
Unit('37 tempC').convert_to('tempF') #=> 98.6 tempF

Ruby-units will raise an exception if you attempt to create a temperature unit that would fall below absolute zero.

Unit math on temperatures is fairly limited.

'100 tempC'.unit + '10 degC'.unit # '110 tempC'.unit
'100 tempC'.unit - '10 degC'.unit # '90 tempC'.unit
'100 tempC'.unit + '50 tempC'.unit # exception
'100 tempC'.unit - '50 tempC'.unit # '50 degC'.unit
'50 tempC'.unit - '100 tempC'.unit # '-50 degC'.unit
'100 tempC'.unit * [scalar] # '100*scalar tempC'.unit
'100 tempC'.unit / [scalar] # '100/scalar tempC'.unit
'100 tempC'.unit * [unit] # exception
'100 tempC'.unit / [unit] # exception
'100 tempC'.unit ** N # exception

'100 tempC'.unit >> 'degC' #=> '100 degC'.unit
Unit('100 tempC') + Unit('10 degC') # '110 tempC'.unit
Unit('100 tempC') - Unit('10 degC') # '90 tempC'.unit
Unit('100 tempC') + Unit('50 tempC') # exception
Unit('100 tempC') - Unit('50 tempC') # '50 degC'.unit
Unit('50 tempC') - Unit('100 tempC') # '-50 degC'.unit
Unit('100 tempC') * [scalar] # '100*scalar tempC'.unit
Unit('100 tempC') / [scalar] # '100/scalar tempC'.unit
Unit('100 tempC') * [unit] # exception
Unit('100 tempC') / [unit] # exception
Unit('100 tempC') ** N # exception

Unit('100 tempC').convert_to('degC') #=> Unit('100 degC')
This conversion references the 0 point on the scale of the temperature unit

'100 degC'.unit >> 'tempC' #=> '-173 tempC'.unit
Unit('100 degC').convert_to('tempC') #=> '-173 tempC'.unit
These conversions are always interpreted as being relative to absolute zero.
Conversions are probably better done like this...

'0 tempC'.unit + '100 degC'.unit #=> '100 tempC'.unit
Unit('0 tempC') + Unit('100 degC') #=> Unit('100 tempC')

## Defininig Units

It is possible to define new units or redefine existing ones.

### Define New Unit

The easiest approach is to define a unit in terms of other units.

Unit.define!("foobar") do |foobar|
foobar.definition = Unit("1 foo") * Unit("1 bar") # anything that results in a Unit object
foobar.aliases = %w{foobar fb} # array of synonyms for the unit
foobar.display_name = "Foobar" # How unit is displayed when output
end

### Redefine Existing Unit

Redefining a unit allows the user to change a single aspect of a definition without having to re-create the entire definition.
This is useful for changing display names, adding aliases, etc.

Unit.redefine!("cup") do |cup|
cup.display_name = "cup"
end

0 comments on commit 732dc8d

Please sign in to comment.