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.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#abbreviationObject Also known as: short

Unlike ordinary magnitudes, units can have names and abbreviations.



138
139
140
# File 'lib/sy/unit.rb', line 138

def abbreviation
  @abbreviation
end

Class Method Details

.abbreviationsObject

Unit abbreviations as a hash of abbreviation => unit pairs.



116
117
118
119
# File 'lib/sy/unit.rb', line 116

def abbreviations
  ii = instances
  Hash[ ii.map( &:short ).zip( ii ).select { |short, _| ! short.nil? } ]
end

.included(target) ⇒ Object

def self.pre_included



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sy/unit.rb', line 40

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|
      

.known_symbolsObject

Full list of known unit names and unit abbreviations.



123
124
125
# File 'lib/sy/unit.rb', line 123

def known_symbols
  instance_names + abbreviations.keys
end

.of(*args) ⇒ Object

Constructor of units of a given quantity.



84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/sy/unit.rb', line 84

def of *args
  

.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.



130
131
132
133
# File 'lib/sy/unit.rb', line 130

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



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/sy/unit.rb', line 7

def self.pre_included target
  class << target
    # Overriding this method from NameMagic mixin makes sure that all Unit
    # subclasses have the same namespace in Unit class, rather then each
    # parametrized subclass its own.
    # 
    def namespace
      SY::Unit
    end

    # Tweaking instance accessor from NameMagic, to make it accept unit
    # abbreviations, and unit names regardless of capitalization
    # 
    def instance arg
      begin
        super # let's first try the original method
      rescue NameError               # if we fail...
        begin # second in order, let's try whether it's an abbreviation
          super instances.find { |inst|
            inst.abbreviation.to_s == arg.to_s if inst.abbreviation
          }
        rescue NameError, TypeError
          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
  end # class << target
end

.standard(args = {}) ⇒ 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.



104
105
106
107
108
109
110
111
112
# File 'lib/sy/unit.rb', line 104

def standard args={}
  args.must_have :quantity, syn!: :of
  qnt = SY::Quantity.instance( args.delete :quantity )
  if args.empty? then
    qnt.standard_unit 
  else
    qnt.new_standard_unit( args )
  end
end

Instance Method Details

#*(other) ⇒ Object

Multiplication: Unit is converted to a magnitude before the operation.



196
197
198
# File 'lib/sy/unit.rb', line 196

def * other
  to_magnitude * other
end

#**(exponent) ⇒ Object

Exponentiation: Unit is converted to a magnitude before the operation.



208
209
210
# File 'lib/sy/unit.rb', line 208

def ** exponent
  to_magnitude ** exponent
end

#+(other) ⇒ Object

Addition: Unit is converted to a magnitude before the operation.



184
185
186
# File 'lib/sy/unit.rb', line 184

def + other
  to_magnitude + other
end

#-(other) ⇒ Object

Subtraction: Unit is converted to a magnitude before the operation.



190
191
192
# File 'lib/sy/unit.rb', line 190

def - other
  to_magnitude - other
end

#/(other) ⇒ Object

Division: Unit is converted to a magnitude before the operation.



202
203
204
# File 'lib/sy/unit.rb', line 202

def / other
  to_magnitude / other
end

#coerce(other) ⇒ Object

Coercion: Unit is converted to a magnitude before coercion is actually performed.



215
216
217
# File 'lib/sy/unit.rb', line 215

def coerce other
  to_magnitude.coerce( other )
end

#initialize(args = {}) ⇒ 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.



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/sy/unit.rb', line 168

def initialize args={}
  if args.has? :abbreviation, syn!: :short then
    @abbreviation = args.delete( :abbreviation ).to_sym
  end
    
  # 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 args
end

#inspectObject

Inspect string for the unit.



233
234
235
# File 'lib/sy/unit.rb', line 233

def inspect
  name.nil? ? inspect_when_anonymous : inspect_when_named
end

#nameObject

Unit name. While named units are typically introduced as constants in all-upper case, their names are then presented in all-lower case.



156
157
158
159
# File 'lib/sy/unit.rb', line 156

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>



253
254
255
# File 'lib/sy/unit.rb', line 253

def quantity_by_prefix prefix
  quantity
end

#reframe(other_quantity) ⇒ Object

Reframing: Unit is converted to a magnitude before reframing.



221
222
223
# File 'lib/sy/unit.rb', line 221

def reframe other_quantity
  to_magnitude.reframe( other_quantity )
end

#short=(unit_abbreviation) ⇒ Object

Unit abbreviation setter (alias for #abbreviation=).



149
150
151
# File 'lib/sy/unit.rb', line 149

def short= unit_abbreviation
  @abbreviation = unit_abbreviation.to_sym
end

#to_sObject

Unit as string.



227
228
229
# File 'lib/sy/unit.rb', line 227

def to_s
  name.nil? ? to_s_when_anonymous : to_s_when_named
end