Class: Eymiha::Units
- Extended by:
- ForwardReferencing
- Defined in:
- lib/eymiha/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.
105 106 107 |
# File 'lib/eymiha/units/units.rb', line 105 def Units.[](name) @@measures[name.to_s] end |
.add_unit(unit, unit_identifier = nil) ⇒ Object
:nodoc:
120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/eymiha/units/units.rb', line 120 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.
92 93 94 95 96 97 |
# File 'lib/eymiha/units/units.rb', line 92 def Units.clear @@measures.clear @@units.clear forward_references_clear self end |
.convert(numeric, unit_identifier) ⇒ Object
:nodoc:
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 189 190 191 |
# File 'lib/eymiha/units/units.rb', line 150 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.
43 44 45 46 47 |
# File 'lib/eymiha/units/units.rb', line 43 def Units.create(name, &block) measure = (@@measures[name.to_s] ||= UnitsMeasure.new) block.call measure if block_given? measure end |
.debug=(value) ⇒ Object
25 26 27 |
# File 'lib/eymiha/units/units.rb', line 25 def self.debug=(value) @@debug = value end |
.defining(measure) ⇒ Object
:nodoc:
146 147 148 |
# File 'lib/eymiha/units/units.rb', line 146 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.
142 143 144 |
# File 'lib/eymiha/units/units.rb', line 142 def Units.defining? @@defining end |
.delete(name) ⇒ Object
Removes the named UnitsMeasure from the Units framework.
87 88 89 |
# File 'lib/eymiha/units/units.rb', line 87 def Units.delete(name) @@measures.delete name.to_s end |
.derive(name, target, &block) ⇒ Object
Creates or extends a UnitsMeasure derived from other UnitsMeasures.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/eymiha/units/units.rb', line 50 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:
209 210 211 |
# File 'lib/eymiha/units/units.rb', line 209 def Units.establish_forward_reference_context(context) # :nodoc: defining context end |
.find_by_derivation(derivation) ⇒ Object
Returns the UnitsMeasure with the given derivation.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/eymiha/units/units.rb', line 67 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, "Multiple UnitsMeasures with same derivation found" end end |
.hold_forward_reference(hold = true) ⇒ Object
:nodoc:
201 202 203 |
# File 'lib/eymiha/units/units.rb', line 201 def Units.hold_forward_reference(hold = true) # :nodoc: @@holding = hold end |
.holding_forward_reference? ⇒ Boolean
:nodoc:
205 206 207 |
# File 'lib/eymiha/units/units.rb', line 205 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.
136 137 138 |
# File 'lib/eymiha/units/units.rb', line 136 def Units.lookup(unit_identifier) @@units[unit_identifier.to_s] || [ ] end |
.make_forward_reference(method, context) ⇒ Object
:nodoc:
193 194 195 |
# File 'lib/eymiha/units/units.rb', line 193 def Units.make_forward_reference(method,context) # :nodoc: @@holding ? nil : create_forward_reference(method,context) end |
.method_missing(method, *args) ⇒ Object
:nodoc:
109 110 111 112 113 |
# File 'lib/eymiha/units/units.rb', line 109 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.
116 117 118 |
# File 'lib/eymiha/units/units.rb', line 116 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.
218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/eymiha/units/units.rb', line 218 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:
197 198 199 |
# File 'lib/eymiha/units/units.rb', line 197 def Units.release_forward_reference(reference = nil) # :nodoc: remove_forward_reference(reference) if reference != nil end |