Class: Quantity::Dimension

Inherits:
Object
  • Object
show all
Defined in:
lib/quantity/dimension.rb,
lib/quantity/dimension/base.rb

Overview

This module attempts to enumerate all of simple, base dimensions. This includes all of the base SI dimensions and some others

Defined Under Namespace

Classes: Currency, Current, DimensionComponent, Information, Length, Luminosity, Mass, Quantity, Substance, Temperature, Time

Constant Summary collapse

@@dimensions =

Class-level methods/vars all known dimensions

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Object

A new dimension

Parameters:

  • options (Hash)

Raises:

  • (ArgumentError)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/quantity/dimension.rb', line 104

def initialize(opts)
  if (opts[:description])
    (@numerators,@denominators) = Dimension.parse_string_form(opts[:description])
  elsif (opts[:numerators])
    @numerators = opts[:numerators]
    @denominators = opts[:denominators]
  else
    raise ArgumentError, "Invalid options for dimension constructors"
  end
  raise ArgumentError, "Dimensions require a numerator" unless @numerators.first.dimension
  @name = opts[:name] || string_form.to_sym
  Dimension.add_alias(self,@name)
  Dimension.add_alias(self,string_form.to_sym)
end

Instance Attribute Details

#denominatorsObject (readonly)

Returns the value of attribute denominators.



97
98
99
# File 'lib/quantity/dimension.rb', line 97

def denominators
  @denominators
end

#nameObject

Returns the value of attribute name.



98
99
100
# File 'lib/quantity/dimension.rb', line 98

def name
  @name
end

#numeratorsObject (readonly)

Returns the value of attribute numerators.



97
98
99
# File 'lib/quantity/dimension.rb', line 97

def numerators
  @numerators
end

Class Method Details

.__reset!Object

Reset the known dimensions. Generally only used for testing.



86
87
88
# File 'lib/quantity/dimension.rb', line 86

def self.__reset!
  @@dimensions = {}
end

.add_alias(dimension, *names) ⇒ Object

Register a dimension to the known list, with the given aliases

Parameters:



72
73
74
75
76
77
# File 'lib/quantity/dimension.rb', line 72

def self.add_alias(dimension, *names)
  names.each do |name|
    raise ArgumentError, "Invalid dimension alias: #{name}" unless (name.to_s =~ /^(\^|\/)/).nil?
    @@dimensions[name] = dimension
  end
end

.add_dimension(name, *aliases) ⇒ Object

DSL component to add a new dimension. Dimension name, reference unit, and aliases. This should be the only way that dimensions are added.

Parameters:

  • name (Symbol)
  • *aliases ([Symbol String])


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/quantity/dimension.rb', line 52

def self.add_dimension(name, *aliases)
  dim = nil
  if name.is_a?(Dimension) 
    dim = name
    name.name = aliases.first if aliases.first
  else
    dim = self.for(name) || self.new({ :name => aliases.first , :description => name})
    self.add_alias(dim,name)
  end
  unless (dim.class == Dimension) 
    dim.name = dim.class.name.downcase.split(/::/).last.to_sym
    self.add_alias(dim,dim.name)
  end
  self.add_alias(dim,*aliases)
  dim
end

.all_dimensions[Dimension]

All known dimensions

Returns:



81
82
83
# File 'lib/quantity/dimension.rb', line 81

def self.all_dimensions
  @@dimensions.values.uniq
end

.for(to) ⇒ Dimension

The dimension for a given symbol, dimension, or string description of a compound dimension

Parameters:

Returns:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/quantity/dimension.rb', line 24

def self.for(to)
  case to
    when Dimension
      if @@dimensions[to.name]
        @@dimensions[to.name]
      else
        add_alias to, to.name
        to
      end
    when Symbol
      if @@dimensions.has_key?(to)
        @@dimensions[to]
      else
        # it's possible we have a non-normalized form, such as mass*length 
        # instead of length * mass
        @@dimensions[string_form(parse_string_form(to)).to_sym]
      end
    when Array
      @@dimensions[string_form(to).to_sym]
    else
      nil
  end
end

Instance Method Details

#*(other) ⇒ Dimension

Dimensional multiplication

Parameters:

Returns:

Raises:

  • (ArgumentError)


133
134
135
136
137
138
# File 'lib/quantity/dimension.rb', line 133

def *(other)
  raise ArgumentError, "Cannot multiply #{self} and #{other.class}" unless other.is_a?(Dimension)
  (new_n, new_d) = Dimension.reduce(@numerators + other.numerators, @denominators + other.denominators)
  existing = Dimension.for([new_n,new_d])
  existing.nil? ? Dimension.new({:numerators => new_n, :denominators => new_d}) : existing
end

#**(other) ⇒ Dimension

Dimensional exponentiation

Parameters:

  • other (Numeric)

Returns:

Raises:

  • (ArgumentError)


153
154
155
156
# File 'lib/quantity/dimension.rb', line 153

def **(other)
  raise ArgumentError, "Dimensions can only be raised to whole powers" unless other.is_a?(Fixnum) && other > 0
  other == 1 ? self : self * self**(other-1)
end

#/(other) ⇒ Dimension

Dimensional division

Parameters:

Returns:

Raises:

  • (ArgumentError)


143
144
145
146
147
148
# File 'lib/quantity/dimension.rb', line 143

def /(other)
  raise ArgumentError, "Cannot divide #{self} by #{other.class}" unless other.is_a?(Dimension)
  (new_n, new_d) = Dimension.reduce(@numerators + other.denominators, @denominators + other.numerators)
  existing = Dimension.for([new_n,new_d])
  existing.nil? ? Dimension.new({:numerators => new_n, :denominators => new_d}) : existing
end

#<=>(other) ⇒ -1 0 1

Spaceship operator for comparable.

Parameters:

  • other (Any)

Returns:

  • (-1 0 1)


167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/quantity/dimension.rb', line 167

def <=>(other)
  if other.is_a?(Dimension)
    if self.is_base? && other.is_base?
      name.to_s <=> other.name.to_s
    elsif other.is_base?
      1
    else
      string_form <=> other.string_form
    end
  else
    nil
  end
end

#inspectString

Returns a developer-friendly representation of this value.

The string will be of the format #<Quantity::Dimension::0x12345678(...)>, where ... is the string returned by #to_s.

Returns:

  • (String)


187
188
189
# File 'lib/quantity/dimension.rb', line 187

def inspect
  sprintf("#<%s:0x%s @name=%s reduced_name=%s>", self.class.name, self.__id__.to_s(16), @name, reduced_name)
end

#is_base?Boolean

Whether or not this is a compound representation of a base dimension

Returns:

  • (Boolean)


160
161
162
# File 'lib/quantity/dimension.rb', line 160

def is_base?
  @denominators.size == 0 && @numerators.size == 1 && @numerators.first.power == 1
end

#reduced_nameObject

The reduced form of a named complex unit

Examples:

Quantity::Dimension.for(:force).reduced_name # => :'mass*length/time^2'


126
127
128
# File 'lib/quantity/dimension.rb', line 126

def reduced_name
  string_form.to_sym
end

#string_formString

Returns a vaguely human-readable and parsable description of this dimension

Returns:

  • (String)


194
195
196
# File 'lib/quantity/dimension.rb', line 194

def string_form
  Dimension.string_form(@numerators,@denominators)
end

#to_sObject



119
120
121
# File 'lib/quantity/dimension.rb', line 119

def to_s
  @name.to_s
end