Class: Units
- Extended by:
- ForwardReferencing
- Defined in:
- lib/units/units.rb
Overview
The Units framework
Units is the top level that you’ll typically never have to deal with directly. While it provides a few chunks of general functionality such as getting defined units and ranking, most of its guts are devoted to defining new UnitsMeasures - unless you’re setting up your own sets of specialized units, you will hardly know it’s here.
Constant Summary collapse
- @@debug =
false
- @@measures =
{}
- @@units =
{}
- @@defining =
nil
- @@holding =
nil
Class Method Summary collapse
-
.[](name) ⇒ Object
Returns the named UnitsMeasure.
-
.add_unit(unit, unit_identifier = nil) ⇒ Object
:nodoc:.
-
.clear ⇒ Object
Clears the Units framework of all defined elements.
-
.convert(numeric, unit_identifier) ⇒ Object
:nodoc:.
-
.create(name, &block) ⇒ Object
Creates or extends a UnitsMeasure.
- .debug=(value) ⇒ Object
-
.defining(measure) ⇒ Object
:nodoc:.
-
.defining? ⇒ Boolean
Answers the question of whether a UnitsMeasure is being defined with the instance if true, or nil if false.
-
.delete(name) ⇒ Object
Removes the named UnitsMeasure from the Units framework.
-
.derive(name, target, &block) ⇒ Object
Creates or extends a UnitsMeasure derived from other UnitsMeasures.
-
.establish_forward_reference_context(context) ⇒ Object
:nodoc:.
-
.find_by_derivation(derivation) ⇒ Object
Returns the UnitsMeasure with the given derivation.
-
.hold_forward_reference(hold = true) ⇒ Object
:nodoc:.
-
.holding_forward_reference? ⇒ Boolean
:nodoc:.
-
.lookup(unit_identifier) ⇒ Object
Returns an Array of UnitsUnit associated with a singular, plural or abbreviated name.
-
.make_forward_reference(method, context) ⇒ Object
:nodoc:.
-
.method_missing(method, *args) ⇒ Object
:nodoc:.
-
.names_of(units_measure) ⇒ Object
Returns an Array containing the names of a given UnitsMeasure.
-
.rank(unit_choices = {}, samples = [], &numeric_ranker) ⇒ Object
Given a Hash of units to raking weights, a set of samples, and optionally a block that returns rankings, returns an Array of units ordered by best weighted fit over the samples.
-
.release_forward_reference(reference = nil) ⇒ Object
:nodoc:.
-
.size ⇒ Object
Returns the number of defined UnitsMeasures.
-
.units_measures ⇒ Object
Returns an Array of the defined UnitsMeasures.
Class Method Details
.[](name) ⇒ Object
Returns the named UnitsMeasure.
102 103 104 |
# File 'lib/units/units.rb', line 102 def Units.[](name) @@measures[name.to_s] end |
.add_unit(unit, unit_identifier = nil) ⇒ Object
:nodoc:
117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/units/units.rb', line 117 def Units.add_unit(unit,unit_identifier=nil) # :nodoc: if unit_identifier if (element = @@units[unit_identifier]) @@units[unit_identifier] += [ unit ] unless element.index(unit) else @@units[unit_identifier] = [ unit ] end else add_unit unit, unit.name add_unit unit, unit.plural unit.abbrevs.each { |abbrev| add_unit unit, abbrev } end end |
.clear ⇒ Object
Clears the Units framework of all defined elements.
89 90 91 92 93 94 |
# File 'lib/units/units.rb', line 89 def Units.clear @@measures.clear @@units.clear forward_references_clear self end |
.convert(numeric, unit_identifier) ⇒ Object
:nodoc:
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/units/units.rb', line 147 def Units.convert(numeric,unit_identifier) # :nodoc: puts "Units:convert #{numeric} #{unit_identifier}" if @@debug if (candidates = lookup(unit_identifier)).size == 0 puts @@units.keys.sort.join(" ") if @@debug puts " no candidates!" if @@debug raise MissingUnitsException.new(unit_identifier.to_s) elsif !defining? if candidates.size > 1 raise AmbiguousUnitsException.new(unit_identifier.to_s) else unit = candidates[0] NumericWithUnits.new(numeric,unit) end else if candidates.size == 1 units = candidates else units = candidates.select { |candidate| @@defining == candidate.units_system.units_measure } units = candidates.select { |candidate| @@defining.derived[candidate.units_measure] } if units.size == 0 end case units.size when 0 then raise MissingUnitsException.new(unit_identifier.to_s) when 1 then unit = units[0] if unit.equals.kind_of? Array element = unit.equals[0] value = NumericWithUnits. new(numeric*element.numeric,element.unit) else value = NumericWithUnits. new(numeric*unit.equals.numeric,unit.equals.unit) end value.original = numeric.unite(unit) value else raise AmbiguousUnitsException.new(unit_identifier.to_s) end end end |
.create(name, &block) ⇒ Object
Creates or extends a UnitsMeasure.
41 42 43 44 45 |
# File 'lib/units/units.rb', line 41 def Units.create(name, &block) measure = (@@measures[name.to_s] ||= UnitsMeasure.new) block.call measure if block_given? measure end |
.debug=(value) ⇒ Object
23 24 25 |
# File 'lib/units/units.rb', line 23 def self.debug=(value) @@debug = value end |
.defining(measure) ⇒ Object
:nodoc:
143 144 145 |
# File 'lib/units/units.rb', line 143 def Units.defining(measure) # :nodoc: @@defining = measure end |
.defining? ⇒ Boolean
Answers the question of whether a UnitsMeasure is being defined with the instance if true, or nil if false.
139 140 141 |
# File 'lib/units/units.rb', line 139 def Units.defining? @@defining end |
.delete(name) ⇒ Object
Removes the named UnitsMeasure from the Units framework.
84 85 86 |
# File 'lib/units/units.rb', line 84 def Units.delete(name) @@measures.delete name.to_s end |
.derive(name, target, &block) ⇒ Object
Creates or extends a UnitsMeasure derived from other UnitsMeasures.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/units/units.rb', line 48 def Units.derive(name, target, &block) measure = ( @@measures[name.to_s] = if target.kind_of? UnitsMeasure if target.derived && (derived = find_by_derivation target.derived) derived else target end else Units.create(target.to_s) end ) block.call measure if block_given? measure end |
.establish_forward_reference_context(context) ⇒ Object
:nodoc:
206 207 208 |
# File 'lib/units/units.rb', line 206 def Units.establish_forward_reference_context(context) # :nodoc: defining context end |
.find_by_derivation(derivation) ⇒ Object
Returns the UnitsMeasure with the given derivation.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/units/units.rb', line 64 def Units.find_by_derivation(derivation) matches = @@measures.values.uniq.select { |measure| if measure.derived measure == derivation elsif derivation.size == 1 a = derivation.to_a[0] a[0] == measure and a[1] == 1 else false end } case matches.size when 0 then nil when 1 then matches[0] else raise UnitsException.new( "Multiple UnitsMeasures with same derivation found") end end |
.hold_forward_reference(hold = true) ⇒ Object
:nodoc:
198 199 200 |
# File 'lib/units/units.rb', line 198 def Units.hold_forward_reference(hold = true) # :nodoc: @@holding = hold end |
.holding_forward_reference? ⇒ Boolean
:nodoc:
202 203 204 |
# File 'lib/units/units.rb', line 202 def Units.holding_forward_reference? # :nodoc: @@holding end |
.lookup(unit_identifier) ⇒ Object
Returns an Array of UnitsUnit associated with a singular, plural or abbreviated name.
133 134 135 |
# File 'lib/units/units.rb', line 133 def Units.lookup(unit_identifier) @@units[unit_identifier.to_s] || [ ] end |
.make_forward_reference(method, context) ⇒ Object
:nodoc:
190 191 192 |
# File 'lib/units/units.rb', line 190 def Units.make_forward_reference(method,context) # :nodoc: @@holding ? nil : create_forward_reference(method,context) end |
.method_missing(method, *args) ⇒ Object
:nodoc:
106 107 108 109 110 |
# File 'lib/units/units.rb', line 106 def Units.method_missing(method,*args) # :nodoc: measure = self[method] raise UnitsException.new("UnitsMeasure '#{method}' undefined") if !measure measure end |
.names_of(units_measure) ⇒ Object
Returns an Array containing the names of a given UnitsMeasure.
113 114 115 |
# File 'lib/units/units.rb', line 113 def Units.names_of(units_measure) @@measures.keys.select { |name| @@measures[name].equal? units_measure } end |
.rank(unit_choices = {}, samples = [], &numeric_ranker) ⇒ Object
Given a Hash of units to raking weights, a set of samples, and optionally a block that returns rankings, returns an Array of units ordered by best weighted fit over the samples. Like golf, low scores rank best. In absence of a block, ranking is based on the number of unit values whose magnitudes are between 1 and 10.
215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/units/units.rb', line 215 def Units.rank(unit_choices = {}, samples = [], &numeric_ranker) # :yields: n if block_given? scores = {} samples.each {|s| unit_choices.each {|uc,w| scores[uc] = (scores[uc] || 0) + w*(yield s.convert(uc).numeric) } } scores.sort {|e1,e2| -(e1[1] <=> e2[1])}.collect {|s| s[0]} else rank(unit_choices,samples) { |n| e = ((((n.abs)-5.5).abs-4.5).at_least(0)) (e == 0) ? 0 : (e == 1)? 0 : -(e + 1/(1-e)) } end end |
.release_forward_reference(reference = nil) ⇒ Object
:nodoc:
194 195 196 |
# File 'lib/units/units.rb', line 194 def Units.release_forward_reference(reference = nil) # :nodoc: remove_forward_reference(reference) if reference != nil end |