Class: CleanHash

Inherits:
Object
  • Object
show all
Defined in:
lib/clean-hash/mutex_hash.rb,
lib/clean-hash/base.rb,
lib/clean-hash/deep_merge.rb,
lib/clean-hash/hash_pollute.rb

Overview

Thread safe hash

Defined Under Namespace

Classes: DeepMerge, MutexHash

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, mode = nil) ⇒ CleanHash

Returns a new instance of CleanHash.



2
3
4
5
6
7
8
9
10
11
12
# File 'lib/clean-hash/base.rb', line 2

def initialize data, mode=nil
  @data = data
  @mode = mode

  case mode
  when :safe
    @is_safe = true
  else
    @is_strict = true if mode
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



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
78
79
80
81
82
# File 'lib/clean-hash/base.rb', line 52

def method_missing name, *args
  m = name.to_s

  if m.end_with?('=')
    m = m.sub('=', '')

    __error_set if @is_strict && !key?(m)

    value = args.first

    if @is_safe
      value = value.to_s if value.is_a?(Symbol)

      unless value.nil? || value.is_a?(Hash) || value.is_a?(Numeric) || value.is_a?(String)
        raise ArgumentError.new('Unsupported safe type: %s' % value.class)
      end
    end

    m = m.to_sym if @data[m].nil?

    @data[m] = value
  elsif m.end_with?('?')
    begin
      !__value_for(m.sub('?', '')).nil?
    rescue NoMethodError
      false
    end
  else
    __value_for m
  end
end

Class Method Details

.pollute!Object



2
3
4
5
6
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
39
40
41
42
43
44
45
46
# File 'lib/clean-hash/hash_pollute.rb', line 2

def self.pollute!
  ::Hash.class_eval do
    # merge but to not overwrite keys
    def deep_merge hash
      klass = ::CleanHash::DeepMerge
      klass[deep_clone].deep_merge klass[hash]
    end

    # true clone of the hash with 0 references to the old one
    def deep_clone
      Marshal.load(Marshal.dump(self))
    end

    def to_ch mode=nil
      if mode.is_a?(Array)
        for key in keys
          raise ArgumentError, 'CleanHash key "%s" not allowed' % key unless mode.include?(key)
        end

        for key in mode
          self[key] = nil unless key?(key)
        end

        ::CleanHash.new self, :strict
      else
        supported = %i{safe mutex strict}
        raise ArgumentError, 'Unsupported type "%s", supported: %s' % [mode, supported] if mode && !supported.include?(mode)

        if mode == :mutex
          ::CleanHash::MutexHash.new self
        else
          ::CleanHash.new self, mode
        end
      end
    end
  end

  ::Array.class_eval do
    # coverts keys to empty hash methods and returns read_only hash
    def to_ch strict=false
      hash = inject({}) { |h, key| h[key] = nil; h }
      ::CleanHash.new hash, :strict
    end
  end
end

Instance Method Details

#[](key) ⇒ Object



24
25
26
# File 'lib/clean-hash/base.rb', line 24

def [] key
  __value_for key.to_s
end

#[]=(key, value) ⇒ Object



28
29
30
31
# File 'lib/clean-hash/base.rb', line 28

def []= key, value
  __error_set if @is_strict && !key?(key)
  @data[key.to_sym] = value
end

#key?(name) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
36
37
38
# File 'lib/clean-hash/base.rb', line 33

def key? name
  __value_for name
  true
rescue NoMethodError
  false
end

#keysObject



40
41
42
# File 'lib/clean-hash/base.rb', line 40

def keys
  @data.keys
end

#to_aryObject

for puts



20
21
22
# File 'lib/clean-hash/base.rb', line 20

def to_ary
  [@data]
end

#to_hObject



48
49
50
# File 'lib/clean-hash/base.rb', line 48

def to_h
  @data
end

#to_jsonObject

for debug



15
16
17
# File 'lib/clean-hash/base.rb', line 15

def to_json
  JSON.pretty_generate @data
end

#valuesObject



44
45
46
# File 'lib/clean-hash/base.rb', line 44

def values
  @data.values
end