Module: SY::Unit
- Includes:
- NameMagic
- Defined in:
- lib/sy/unit.rb
Overview
This class represents a unit of measurement – a predefined magnitude of a metrological quantity.
Constant Summary collapse
- PROTECTED_NAMES =
[ "kilogram" ]
Instance Attribute Summary collapse
-
#abbreviation ⇒ Object
(also: #short)
Unlike ordinary magnitudes, units can have names and abbreviations.
-
#warns ⇒ Object
(also: #warns?)
Whether the unit warns when the module in which unit method mixin is included contains blatant name collisions with this unit name/abbreviation.
Class Method Summary collapse
-
.abbreviations ⇒ Object
Unit abbreviations as a hash of abbreviation => unit pairs.
-
.included(target) ⇒ Object
def self.instance.
-
.instance(arg) ⇒ Object
Tweaking instance accessor from NameMagic to make it accept unit abbreviations and unit names regardless of capitalization.
-
.known_symbols ⇒ Object
Full list of known unit names and unit abbreviations.
-
.of(quantity, **nn) ⇒ Object
Constructor of units of a given quantity.
-
.parse_sps_using_all_prefixes(sps) ⇒ Object
Parses an SPS, curring it with known unit names and abbreviations, and all known full and short prefixes.
- .pre_included(target) ⇒ Object
-
.standard(of: nil, **nn) ⇒ Object
Standard unit constructor.
Instance Method Summary collapse
-
#*(other) ⇒ Object
Multiplication: Unit is converted to a magnitude before the operation.
-
#**(exponent) ⇒ Object
Exponentiation: Unit is converted to a magnitude before the operation.
-
#+(other) ⇒ Object
Addition: Unit is converted to a magnitude before the operation.
-
#-(other) ⇒ Object
Subtraction: Unit is converted to a magnitude before the operation.
-
#/(other) ⇒ Object
Division: Unit is converted to a magnitude before the operation.
-
#coerce(other) ⇒ Object
Coercion: Unit is converted to a magnitude before coercion is actually performed.
-
#initialize(short: nil, warns: true, **nn) ⇒ Object
Constructor of units provides support for one additional named argument: :abbreviation, alias :short.
-
#inspect ⇒ Object
Inspect string for the unit.
-
#name ⇒ Object
(also: #ɴ)
Unit name.
-
#quantity_by_prefix(prefix) ⇒ Object
Some prefixes of some units are almost exclusively used in certain areas of science or engineering, and their appearance would indicate such specific quantity.
-
#reframe(other_quantity) ⇒ Object
Reframing: Unit is converted to a magnitude before reframing.
-
#short=(unit_abbreviation) ⇒ Object
Unit abbreviation setter (alias for #abbreviation=).
-
#to_s ⇒ Object
Unit as string.
Instance Attribute Details
#abbreviation ⇒ Object Also known as: short
Unlike ordinary magnitudes, units can have names and abbreviations.
161 162 163 |
# File 'lib/sy/unit.rb', line 161 def abbreviation @abbreviation end |
#warns ⇒ Object Also known as: warns?
Whether the unit warns when the module in which unit method mixin is included contains blatant name collisions with this unit name/abbreviation.
167 168 169 |
# File 'lib/sy/unit.rb', line 167 def warns @warns end |
Class Method Details
.abbreviations ⇒ Object
Unit abbreviations as a hash of abbreviation => unit pairs.
139 140 141 142 |
# File 'lib/sy/unit.rb', line 139 def abbreviations ii = instances Hash[ ii.map( &:short ).zip( ii ).select { |short, _| ! short.nil? } ] end |
.included(target) ⇒ Object
def self.instance
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/sy/unit.rb', line 58 def self.included target target.class_exec do # Let's set up the naming hook for NameMagic: name_set_closure do |name, new_instance, old_name| |
.instance(arg) ⇒ Object
Tweaking instance accessor from NameMagic to make it accept unit abbreviations and unit names regardless of capitalization
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/sy/unit.rb', line 23 def self.instance arg puts "SY::Unit module #instance method activated" if SY::DEBUG begin super # let's first try the original method .tap { puts "original #instance method provided by NameMagic succeeded" if SY::DEBUG } rescue NameError # if we fail... puts "original #instance method provided by NameMagic returned NameError" if SY::DEBUG begin # second in order, let's try whether it's an abbreviation puts "trying whether the argument is an abbreviation" if SY::DEBUG rslt = instances.find { |unit_inst| if unit_inst.abbreviation then if unit_inst.abbreviation.to_s == arg.to_s then puts "For supplied argument #{arg} (#{arg.class}), it seems that " + "unit #{unit_inst} of quantity #{unit_inst.quantity} has abbreviation " + "#{unit_inst.abbreviation} matching it." if SY::DEBUG true else false end end # inst.abbreviation.to_s == arg.to_s if inst.abbreviation } fail NameError if rslt.nil? # if nothing found, super need not be called super rslt rescue NameError, TypeError puts "failed, we'll now try to upcase the argument in case of all-downcase argument" if SY::DEBUG begin # finally, let's try upcase if we have all-downcase arg super arg.to_s.upcase rescue NameError # if not, tough luck raise NameError, "Unknown unit symbol: #{which}" end end end end |
.known_symbols ⇒ Object
Full list of known unit names and unit abbreviations.
146 147 148 |
# File 'lib/sy/unit.rb', line 146 def known_symbols instance_names + abbreviations.keys end |
.of(quantity, **nn) ⇒ Object
Constructor of units of a given quantity.
119 120 121 |
# File 'lib/sy/unit.rb', line 119 def of quantity, **nn quantity.unit **nn end |
.parse_sps_using_all_prefixes(sps) ⇒ Object
Parses an SPS, curring it with known unit names and abbreviations, and all known full and short prefixes.
153 154 155 156 |
# File 'lib/sy/unit.rb', line 153 def parse_sps_using_all_prefixes sps puts "Unit about to sps parse (#{sps})" if SY::DEBUG SY::PREFIX_TABLE.parse_sps( sps, known_symbols ) end |
.pre_included(target) ⇒ Object
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/sy/unit.rb', line 9 def self.pre_included target class << target # Overriding this method from NameMagic mixin ensures, that all Unit # subclasses use common namespace (Unit), rather than each their own. # def namespace SY::Unit end end end |
.standard(of: nil, **nn) ⇒ Object
Standard unit constructor. In absence of other named arguments, standard unit of the specified quantity is merely retrieved. If other named arguments than :quantity (alias :of) are supplied, they are forwarded to Quantity#new_standard_unit method, that resets the standard unit of the specified quantity. Note that :amount for standard units, if supplied, has special meaning of setting the relationship of that quantity.
130 131 132 133 134 135 |
# File 'lib/sy/unit.rb', line 130 def standard( of: nil, **nn ) puts "Constructing a standard unit of #{of}." if SY::DEBUG fail ArgumentError, ":of argument missing!" if of.nil? qnt = SY::Quantity.instance( of ) nn.empty? ? qnt.standard_unit : qnt.new_standard_unit( **nn ) end |
Instance Method Details
#*(other) ⇒ Object
Multiplication: Unit is converted to a magnitude before the operation.
227 228 229 |
# File 'lib/sy/unit.rb', line 227 def * other to_magnitude * other end |
#**(exponent) ⇒ Object
Exponentiation: Unit is converted to a magnitude before the operation.
239 240 241 |
# File 'lib/sy/unit.rb', line 239 def ** exponent to_magnitude ** exponent end |
#+(other) ⇒ Object
Addition: Unit is converted to a magnitude before the operation.
215 216 217 |
# File 'lib/sy/unit.rb', line 215 def + other to_magnitude + other end |
#-(other) ⇒ Object
Subtraction: Unit is converted to a magnitude before the operation.
221 222 223 |
# File 'lib/sy/unit.rb', line 221 def - other to_magnitude - other end |
#/(other) ⇒ Object
Division: Unit is converted to a magnitude before the operation.
233 234 235 |
# File 'lib/sy/unit.rb', line 233 def / other to_magnitude / other end |
#coerce(other) ⇒ Object
Coercion: Unit is converted to a magnitude before coercion is actually performed.
246 247 248 |
# File 'lib/sy/unit.rb', line 246 def coerce other to_magnitude.coerce( other ) end |
#initialize(short: nil, warns: true, **nn) ⇒ Object
Constructor of units provides support for one additional named argument: :abbreviation, alias :short. (This is in addition to :name, alias :ɴ named argument provided by NameMagic.) As a general rule, only named units unit should be given abbreviations. In choosing unit names and abbreviations, ambiguity with regard to standard prefixes and abbreviations thereof should also be avoided. Another argument, :warns, Boolean, true by default, determines whether the method warns about name collisions with other methods defined where the SY::ExpressibleInUnits mixin is included.
200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/sy/unit.rb', line 200 def initialize( short: nil, warns: true, **nn ) @abbreviation = short.to_sym if short @warns = warns # does this unit care about blatant name collisions? # FIXME: Here, we would have to watch out for :amount being set # if it is a number, amount is in standard units # however, if it is a magnitude, especially one of another equidimensional quantity, # it estableshes a relationship between this and that quantity. It means that # the unit amount automatically becomes ... one ... and such relationship can # only be established for standard quantity super nn end |
#inspect ⇒ Object
Inspect string for the unit.
264 265 266 |
# File 'lib/sy/unit.rb', line 264 def inspect name.nil? ? inspect_when_anonymous : inspect_when_named end |
#name ⇒ Object Also known as: ɴ
Unit name. While named units are typically introduced as constants in all-upper case, their names are then presented in all-lower case.
185 186 187 188 |
# File 'lib/sy/unit.rb', line 185 def name |
#quantity_by_prefix(prefix) ⇒ Object
Some prefixes of some units are almost exclusively used in certain areas of science or engineering, and their appearance would indicate such specific quantity. By default, this method simply returns unit’s own quantity unchanged. But it is expected that the method will be overriden by a singleton method in those units, which have area-specific prefixes. For example, centimetre, typical for civil engineering, could cause reframing into its own CentimetreLength quantity. Assuming METRE unit, this could be specified for example by: <tt> METRE.define_singleton_method :quantity_by_prefix do |full_prefix|
case full_prefix
when :centi then CentimetreLength
else self.quantity end
end </tt>
284 285 286 |
# File 'lib/sy/unit.rb', line 284 def quantity_by_prefix prefix quantity end |
#reframe(other_quantity) ⇒ Object
Reframing: Unit is converted to a magnitude before reframing.
252 253 254 |
# File 'lib/sy/unit.rb', line 252 def reframe other_quantity to_magnnitude.reframe( other_quantity ) end |
#short=(unit_abbreviation) ⇒ Object
Unit abbreviation setter (alias for #abbreviation=).
178 179 180 |
# File 'lib/sy/unit.rb', line 178 def short= unit_abbreviation @abbreviation = unit_abbreviation.to_sym end |
#to_s ⇒ Object
Unit as string.
258 259 260 |
# File 'lib/sy/unit.rb', line 258 def to_s name.nil? ? to_s_when_anonymous : to_s_when_named end |