Class: CleanHash

Inherits:
Object
  • Object
show all
Defined in:
lib/clean-hash/types/struct_type.rb,
lib/clean-hash/deep_merge.rb,
lib/clean-hash/hash_pollute.rb,
lib/clean-hash/types/safe_type.rb,
lib/clean-hash/types/indifferent_type.rb

Overview

raise error if accessing hash with method and key not found stict_hash = { foo: :bar }.to_ch :strict stict_hash # nil stict_hash.foo # :bar stict_hash.not_found # ArgumentError

Direct Known Subclasses

Safe

Defined Under Namespace

Classes: DeepMerge, Safe

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ CleanHash

Returns a new instance of CleanHash.



10
11
12
# File 'lib/clean-hash/types/indifferent_type.rb', line 10

def initialize data
  @data = data
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/clean-hash/types/indifferent_type.rb', line 70

def method_missing name, *args, &block
  return @data.send(name, *args, &block) if @data.respond_to?(name)

  m = name.to_s

  if m.end_with?('=')
    m = m.sub('=', '')
    self[m] = args.first
  elsif m.end_with?('?')
    !self[m.sub('?', '')].nil?
  elsif block
    self[m] = block
  else
    _method_missing_key m
  end
end

Class Method Details

.create_struct(hash) ⇒ Object

Raises:

  • (ArgumentError)


6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/clean-hash/types/struct_type.rb', line 6

def self.create_struct hash
  raise ArgumentError.new('Not a hash') unless hash.is_a?(Hash)

  name = 'DynStruct_' + hash.keys.join('_')
  CH_STRUCTS[name] ||= ::Struct.new(name, *hash.keys.sort)

  CH_STRUCTS[name].new.tap do |o|
    hash.each do |k, v|
      o.send('%s=' % k, v) unless v.nil?
    end
  end
end

.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
# 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)
        if not_alowed = (keys - mode).first
          raise ArgumentError.new('CleanHash option "%s" is not alowed (%s)' % [not_alowed, mode.join(', ')])
        end

        mode.each { |el| self[el] = nil if self[el].nil? }
        CleanHash.create_struct self
      else
        CleanHash.new self
      end
    end
  end
end

Instance Method Details

#[](key) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/clean-hash/types/indifferent_type.rb', line 51

def [] key
  data = @data[key]
  data = @data[key.to_s]   if data.nil? && !key.is_a?(String)
  data = @data[key.to_sym] if data.nil? && key.respond_to?(:to_sym)

  if data.is_a?(Hash)
    self.class.new data
  else
    data
  end
end

#[]=(key, value) ⇒ Object



63
64
65
66
67
68
# File 'lib/clean-hash/types/indifferent_type.rb', line 63

def []= key, value
  delete key
  MUTEX.synchronize do
    @data[key] = value
  end
end

#delete(key) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/clean-hash/types/indifferent_type.rb', line 34

def delete key
  out = []
  out.push @data.delete(key)
  out.push @data.delete(key.to_s)
  out.push @data.delete(key.to_sym) if key.respond_to?(:to_sym)
  out.each { |el| return el unless el.nil? }
  nil
end

#keyObject

overload key ruby method because it is common hash key name still accessible via to_h.key



26
27
28
# File 'lib/clean-hash/types/indifferent_type.rb', line 26

def key
  self[:key]
end

#key?(name) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
# File 'lib/clean-hash/types/indifferent_type.rb', line 30

def key? name
  @data.key?(name) || @data.key?(name.to_s) || (name.respond_to?(:to_sym) ? @data.key?(name.to_sym) : nil)
end

#to_aryObject

for puts



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

def to_ary
  [@data]
end

#to_hObject



43
44
45
# File 'lib/clean-hash/types/indifferent_type.rb', line 43

def to_h
  @data
end

#to_json(*args) ⇒ Object

for debug



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

def to_json
  JSON.pretty_generate @data
end