Class: Horologium::Configuration
- Inherits:
-
Object
- Object
- Horologium::Configuration
- Defined in:
- lib/horologium/configuration.rb,
sig/horologium/configuration.rbs
Overview
Holds the library's settings: the default precision new instants and durations take when none is asked for, and the time scales an instant can be read in. Both are set once, inside configure, and frozen afterwards, so behaviour does not depend on when in the process' life an object is read.
Constant Summary collapse
- BUILT_IN_SCALES =
The scales the library ships with. They are registered before the library is configured.
{ tai: Scales::TAI, tt: Scales::TT, tdb: Scales::TDB, utc: Scales::UTC }.freeze
- LEAP_SECOND_HORIZONS =
The recognised ways to handle a leap second past the data's horizon.
%i[extrapolate raise].freeze
Instance Attribute Summary collapse
-
#default_precision ⇒ Symbol
The default precision,
:standarduntil configured. -
#leap_second_horizon ⇒ Symbol
What UTC does with a date past the point the leap second data vouches for.
-
#leap_second_source ⇒ #tai_utc_at
The source UTC reads its leap seconds from.
Instance Method Summary collapse
-
#freeze ⇒ self
Freezes the configuration and the scales with it, so neither changes once the library is configured.
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
-
#register_scale(name, scale) ⇒ Class
Registers a time scale under a name, so an instant can be read in it with Instant#to.
-
#scale(name) ⇒ Class
The scale registered under a name.
-
#scale_names ⇒ Array<Symbol>
The names an instant can be read in, the built-in scales and any scale #register_scale added.
-
#validate_scale!(scale) ⇒ void
Checks that a scale can be read in: a class implementing both halves of Scales::Base.
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
45 46 47 48 49 50 |
# File 'lib/horologium/configuration.rb', line 45 def initialize @default_precision = :standard @scales = BUILT_IN_SCALES.dup @leap_second_source = Data::LeapSeconds @leap_second_horizon = :extrapolate end |
Instance Attribute Details
#default_precision ⇒ Symbol
Returns the default precision, :standard until configured.
20 21 22 |
# File 'lib/horologium/configuration.rb', line 20 def default_precision @default_precision end |
#leap_second_horizon ⇒ Symbol
What UTC does with a date past the point the leap second data vouches
for. :extrapolate, the default, reads it in UTC with the last known
offset and marks the reading :extrapolated. :raise refuses it with
OutOfDataRangeError, for a pipeline that must not lean on an offset a
new leap second could overturn.
43 44 45 |
# File 'lib/horologium/configuration.rb', line 43 def leap_second_horizon @leap_second_horizon end |
#leap_second_source ⇒ #tai_utc_at
The source UTC reads its leap seconds from. It answers tai_utc_at with
TAI - UTC at a point in UTC, given a Julian Day Number: a day's 0h for a
whole number, or part way through a day where a fraction is added, which
UTC asks for to read the pre-1972 drift within a day. A source that steps
only at whole days can answer a fraction with the offset at its 0h.
Data::LeapSeconds, over the iers gem, is the default; a caller with its
own leap second data can set another here.
34 35 36 |
# File 'lib/horologium/configuration.rb', line 34 def leap_second_source @leap_second_source end |
Instance Method Details
#freeze ⇒ self
Freezes the configuration and the scales with it, so neither changes once the library is configured.
169 170 171 172 |
# File 'lib/horologium/configuration.rb', line 169 def freeze @scales.freeze super end |
#register_scale(name, scale) ⇒ Class
Registers a time scale under a name, so an instant can be read in it with Instant#to. The scale is a class implementing Scales::Base: it says how to read TAI in the scale, and how to read the scale back in TAI. Registering a name that is already taken replaces the scale under it, so a scale the library ships can be swapped for another model.
A scale that does not implement both of them is refused here, at boot, rather than when an instant is first read in it.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/horologium/configuration.rb', line 139 def register_scale(name, scale) if @scales.frozen? raise ConfigurationError, "the configuration is already frozen" end unless name.is_a?(Symbol) raise ConfigurationError, "a scale is registered under a Symbol, got #{name.inspect}" end validate_scale!(scale) @scales[name] = scale end |
#scale(name) ⇒ Class
The scale registered under a name.
159 160 161 162 163 |
# File 'lib/horologium/configuration.rb', line 159 def scale(name) @scales.fetch(name) do raise UnknownScaleError.new(name, scale_names) end end |
#scale_names ⇒ Array<Symbol>
The names an instant can be read in, the built-in scales and any scale #register_scale added.
56 57 58 |
# File 'lib/horologium/configuration.rb', line 56 def scale_names @scales.keys end |
#validate_scale!(scale) ⇒ void
This method returns an undefined value.
Checks that a scale can be read in: a class implementing both halves of Scales::Base. A subclass that inherits either one from Scales::Base would raise NotImplementedError on the first conversion, so it is refused here instead.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/horologium/configuration.rb', line 184 def validate_scale!(scale) unless scale.is_a?(Class) && scale < Scales::Base raise ConfigurationError, "a scale must be a subclass of Horologium::Scales::Base, " \ "got #{scale.inspect}" end missing = %i[from_reference to_reference].select do |method| scale.method(method).owner == Scales::Base.singleton_class end return if missing.empty? raise ConfigurationError, "#{scale} does not implement #{missing.join(" or ")}" end |