Class: Factbase::Fact

Inherits:
Object
  • Object
show all
Defined in:
lib/factbase/fact.rb

Overview

Fact.

This is an internal class, it is not supposed to be instantiated directly.

It is possible to use for testing directly, for example to make a fact with a single key/value pair inside:

require 'factbase/fact'
f = Factbase::Fact.new(Mutex.new, { 'foo' => [42, 256, 'Hello, world!'] })
assert_equal(42, f.foo)
Author

Yegor Bugayenko ([email protected])

Copyright

Copyright © 2024 Yegor Bugayenko

License

MIT

Instance Method Summary collapse

Constructor Details

#initialize(mutex, map) ⇒ Fact

Ctor.

Parameters:

  • mutex (Mutex)

    A mutex to use for maps synchronization

  • map (Hash)

    A map of key/value pairs



45
46
47
48
# File 'lib/factbase/fact.rb', line 45

def initialize(mutex, map)
  @mutex = mutex
  @map = map
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args) ⇒ Object

When a method is missing, this method is called.



57
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
# File 'lib/factbase/fact.rb', line 57

def method_missing(*args)
  k = args[0].to_s
  if k.end_with?('=')
    kk = k[0..-2]
    raise "Invalid prop name '#{kk}'" unless kk.match?(/^[a-z_][_a-zA-Z0-9]*$/)
    raise "Prohibited prop name '#{kk}'" if kk == 'to_s'
    v = args[1]
    raise "Prop value can't be nil" if v.nil?
    raise "Prop value can't be empty" if v == ''
    raise "Prop type '#{v.class}' is not allowed" unless [String, Integer, Float, Time].include?(v.class)
    v = v.utc if v.is_a?(Time)
    @mutex.synchronize do
      before = @map[kk]
      return if before == v
      if before.nil?
        @map[kk] = v
        return
      end
      @map[kk] = [@map[kk]] unless @map[kk].is_a?(Array)
      @map[kk] << v
      @map[kk].uniq!
    end
    nil
  elsif k == '[]'
    @map[args[1].to_s]
  else
    v = @map[k]
    if v.nil?
      raise "Can't get '#{k}', the fact is empty" if @map.empty?
      raise "Can't find '#{k}' attribute out of [#{@map.keys.join(', ')}]"
    end
    v.is_a?(Array) ? v[0] : v
  end
end

Instance Method Details

#respond_to?(_method, _include_private = false) ⇒ Boolean

rubocop:disable Style/OptionalBooleanParameter

Returns:

  • (Boolean)


93
94
95
96
# File 'lib/factbase/fact.rb', line 93

def respond_to?(_method, _include_private = false)
  # rubocop:enable Style/OptionalBooleanParameter
  true
end

#respond_to_missing?(_method, _include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/factbase/fact.rb', line 98

def respond_to_missing?(_method, _include_private = false)
  true
end

#to_sString

Convert it to a string.

Returns:

  • (String)

    String representation of it (in JSON)



52
53
54
# File 'lib/factbase/fact.rb', line 52

def to_s
  "[ #{@map.map { |k, v| "#{k}: #{v}" }.join(', ')} ]"
end