Skip to content

Commit ff50514

Browse files
Merge pull request #3 from Kaligo/feature/add-object-deep-fetch
Add Object#deep_fetch
2 parents 93bf623 + 07bb298 commit ff50514

File tree

4 files changed

+65
-44
lines changed

4 files changed

+65
-44
lines changed

Diff for: lib/core_ext/deep_fetch.rb

+16-34
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,32 @@
11
require 'backport_dig' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
2-
require 'singleton'
32

4-
class VarCache
5-
6-
include Singleton
7-
8-
def self.fetch_or_store(key)
9-
instance.fetch_or_store(key)
10-
end
11-
12-
def initialize
13-
@storage = {}
14-
end
15-
16-
def fetch(key)
17-
@storage[key]
18-
end
19-
20-
def store(key)
21-
@storage[key] = attributes(key)
22-
end
23-
24-
def fetch_or_store(key)
25-
fetch(key) || store(key)
26-
end
27-
28-
private
29-
30-
def attributes(key)
31-
key.to_s.split('.')
3+
class Object
4+
def deep_fetch(keys, default = nil)
5+
case keys.length
6+
when 0
7+
self
8+
when 1
9+
self.send(keys.first)
10+
else
11+
self.send(keys.first).deep_fetch(keys[1..-1], default)
3212
end
3313

14+
rescue
15+
default
16+
end
3417
end
3518

3619
class Hash
37-
def deep_fetch(key, default = nil)
38-
keys = VarCache.fetch_or_store(key)
20+
def deep_fetch(keys, default = nil)
3921
value = dig(*keys) rescue default
4022
value.nil? ? default : value # value can be false (Boolean)
4123
end
4224
end
4325

4426
class Array
45-
def deep_fetch(index, default = nil)
46-
indexes = VarCache.fetch_or_store(index).map(&:to_i)
47-
value = dig(*indexes) rescue default
27+
def deep_fetch(keys, default = nil)
28+
indices = keys.map(&:to_i)
29+
value = dig(*indices) rescue default
4830
value.nil? ? default : value # value can be false (Boolean)
4931
end
5032
end

Diff for: lib/json_logic.rb

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
require 'core_ext/stringify_keys'
33
require 'json_logic/truthy'
44
require 'json_logic/operation'
5+
require 'json_logic/var_cache'
6+
57
module JSONLogic
68
def self.apply(logic, data)
79
if logic.is_a?(Array)

Diff for: lib/json_logic/operation.rb

+14-10
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@ module JSONLogic
44
class Operation
55
LAMBDAS = {
66
'var' => ->(v, d) do
7-
if !(d.is_a?(Hash) || d.is_a?(Array))
7+
if v.empty?
88
d
9-
else
10-
if v == [JSONLogic::ITERABLE_KEY]
11-
if d.is_a?(Array)
12-
d
13-
else
14-
d[JSONLogic::ITERABLE_KEY]
15-
end
9+
elsif v == [JSONLogic::ITERABLE_KEY]
10+
if d.is_a?(Hash)
11+
d[JSONLogic::ITERABLE_KEY]
1612
else
17-
d.deep_fetch(*v)
13+
d
1814
end
15+
else
16+
keys = VarCache.fetch_or_store(v[0])
17+
d.deep_fetch(keys, v[1])
18+
end
19+
end,
20+
'missing' => ->(v, d) do
21+
v.select do |val|
22+
keys = VarCache.fetch_or_store(val)
23+
d.deep_fetch(keys).nil?
1924
end
2025
end,
21-
'missing' => ->(v, d) { v.select { |val| d.deep_fetch(val).nil? } },
2226
'missing_some' => ->(v, d) {
2327
present = v[1] & d.keys
2428
present.size >= v[0] ? [] : LAMBDAS['missing'].call(v[1], d)

Diff for: lib/json_logic/var_cache.rb

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
require 'singleton'
2+
3+
class VarCache
4+
5+
include Singleton
6+
7+
def self.fetch_or_store(key)
8+
instance.fetch_or_store(key)
9+
end
10+
11+
def initialize
12+
@storage = {}
13+
end
14+
15+
def fetch(key)
16+
@storage[key]
17+
end
18+
19+
def store(key)
20+
@storage[key] = attributes(key)
21+
end
22+
23+
def fetch_or_store(key)
24+
fetch(key) || store(key)
25+
end
26+
27+
private
28+
29+
def attributes(key)
30+
key.to_s.split('.')
31+
end
32+
33+
end

0 commit comments

Comments
 (0)