Class: Hash

Inherits:
Object show all
Defined in:
lib/shenanigans/hash/extract.rb,
lib/shenanigans/hash/to_ostruct.rb,
lib/shenanigans/hash/has_shape_pred.rb

Instance Method Summary collapse

Instance Method Details

#extract(*ks) ⇒ Object

Returns a new hash only with the specified keys (if present).

Examples:

Key order does not matter

hash = { a: 1, b: 2, c: 3 }
hash.extract(:b, :a) #=> { a: 1, b: 2 }

Missing keys are ignored

hash.extract(:a, :d) #=> { a: 1}


9
10
11
12
# File 'lib/shenanigans/hash/extract.rb', line 9

def extract(*ks)
  existing = keys & ks
  Hash[existing.zip(values_at(*existing))]
end

#has_shape?(shape) ⇒ Boolean

Checks if a hash has a certain structure.

Examples:

Simple hash

h = { k1: 1, k2: "1" }
h.has_shape?(k1: Integer, k2: String) #=> true
h.has_shape?(k1: Class, k2: String) #=> false

Nested hashes

h = { k1: [], k2: { k3: Struct.new("Foo") } }
shape = { k1: Array, k2: { k3: Module } }
h.has_shape?(shape) #=> true

Returns:

  • (Boolean)


12
13
14
15
16
# File 'lib/shenanigans/hash/has_shape_pred.rb', line 12

def has_shape?(shape)
  all? do |k, v|
    Hash === v ? v.has_shape?(shape[k]) : shape[k] === v
  end
end

#to_ostructObject

Recursively converts a Hash and all nested Hashes to OpenStructs. Especially useful for parsing YAML.

Examples:

yaml=<<EOY
subject: Programming Languages
languages:
  - name        : Ruby
    creator     : Matz
  - name        : Python
    creator     : Guido van Rossum
  - name        : Perl
    creator     : Larry Wall
EOY
struct = YAML.load(yaml).to_ostruct
struct.subject #=> "Programming Languages"
struct.languages.first #=> #<OpenStruct name="Ruby", creator="Matz">
struct.languages.first.creator #=> "Matz"


22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/shenanigans/hash/to_ostruct.rb', line 22

def to_ostruct
  arr = map { |k, v|
    case v
    when Hash
      [k, v.to_ostruct]
    when Array
      [k, v.map { |el| el.respond_to?(:to_ostruct) ? el.to_ostruct : el }]
    else
      [k, v]
    end
  }
  OpenStruct.new(Hash[arr])
end