Class: KeyValueName::NumericMarshaler

Inherits:
MarshalerBase show all
Defined in:
lib/key_value_name/marshalers/numeric_marshaler.rb

Overview

Read and write numeric types with a general format string for ‘Kernel#format` (or `Kernel#sprintf`) and `String#scanf`.

This seems like a nice idea, but ruby’s ‘scanf` doesn’t seem to handle all possible format strings. For example, you can format with ‘%.1f`, but scanning with that string does not work. To work around this problem, you can specify a separate `scan_format` that `scanf` can handle; for this example, it would be just `%f`.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(format: '%g', scan_format: nil) ⇒ NumericMarshaler

Returns a new instance of NumericMarshaler.



17
18
19
20
# File 'lib/key_value_name/marshalers/numeric_marshaler.rb', line 17

def initialize(format: '%g', scan_format: nil)
  @format_string = format
  @scan_format_string = scan_format
end

Instance Attribute Details

#format_stringObject (readonly)

Returns the value of attribute format_string.



22
23
24
# File 'lib/key_value_name/marshalers/numeric_marshaler.rb', line 22

def format_string
  @format_string
end

Instance Method Details

#matcherObject



28
29
30
31
32
# File 'lib/key_value_name/marshalers/numeric_marshaler.rb', line 28

def matcher
  # This is the usual regex, except that it also has to match `%x` formats,
  # so it allows hexadecimal whole numbers.
  /[-+]?[0-9]*\.?[0-9a-f]+(?:e[-+]?[0-9]+)?/i
end

#read(string) ⇒ Object



34
35
36
37
38
# File 'lib/key_value_name/marshalers/numeric_marshaler.rb', line 34

def read(string)
  values = string.scanf(scan_format_string)
  raise "failed to scan: #{string}" if values.empty?
  values.first
end

#scan_format_stringObject



24
25
26
# File 'lib/key_value_name/marshalers/numeric_marshaler.rb', line 24

def scan_format_string
  @scan_format_string || format_string
end

#write(value) ⇒ Object



40
41
42
# File 'lib/key_value_name/marshalers/numeric_marshaler.rb', line 40

def write(value)
  format(format_string, value)
end